1

I have this Book class objects (base class: Product)

Book books[5] = {
    Book("Kucuk Prens","FR","Roman","Book",10,15,103061,12,"Kultur yayinlari",10),
    Book("Kucuk Prens1","FR","Roman","Book",10,15,103061,12,"Kultur yayinlari",10),
    Book("Kucuk Prens2","FR","Roman","Book",10,15,103061,12,"Kultur yayinlari",10),
    Book("Kucuk Prens3","FR","Roman","Book",10,15,103061,12,"Kultur yayinlari",10),
    Book("Kucuk Prens4","FR","Roman","Book",10,15,103061,12,"Kultur yayinlari",10)};

And I have a Cart class.

class Cart
{

private:

    int totalPrice;
    Product productList[5]; // kullanıcın seçtiği


public:


};

For instance, I want to add books[1] to productList[]. How can I?

8
  • C-way: use a pointer Product* productList and allocate it dynamically either with new or malloc(). If you want to resize, use realloc(). C++-way: use STL's vector. Commented Dec 16, 2022 at 16:47
  • 1
    Welcome to C++! Do learn about std::vector at the absolute earliest opportunity. Commented Dec 16, 2022 at 16:47
  • 1
    wont work like this: stackoverflow.com/questions/274626/what-is-object-slicing. productList can only contain Products Commented Dec 16, 2022 at 16:47
  • 2
    @A.B. thats a rather misleading suggestion. malloc is wrong. Not clear why you suggest dynamic allocation via new or malloc anyhow. Commented Dec 16, 2022 at 16:48
  • Use a std::vector<std::unique_ptr<Product>> and derive Book from Product. Commented Dec 16, 2022 at 16:55

1 Answer 1

1

First off, you are writing C++, this means you are lucky enough to not have to utilize C arrays/malloc'd pointers, prefer STL containers instead, since they manage the memory for you!

That said, if you want to put derived classes in a base class container, you are going to have to store pointers to that base class, once again, best to use modern C++ and use smart pointers instead, since they are self-managing and will save you the headache of free'ing them:


#include <memory> //smart pointers
#include <vector> //vector, STL container for a dynamically resizable array
#include <string> //string, pretty self explanatory
#include <algorithm> //algorithm, for powerful utility algorithms

class Cart
{

private:

    int totalPrice;
// A vector of smart pointers to our base class
    std::vector<std::unique_ptr<Product>> productList;


public:

    Cart() = default;

    void addProduct(std::unique_ptr<Product>&& product)
    {
// we put our product in the cart using [Move Semantics][1], transferring ownership 
// of the pointer to the cart.
        productList.push_back(std::move(product));
    }

    void removeProduct(std::string_view product_name)
    {
//we use a combination of std::find_if, from the algorithm header, together with a 
//lambda, to remove a product by its name (similar functions can be written using
//different attributes as keys
        auto const& to_remove = std::find_if(productList.begin(), productList.end(), 
        [
            &product_name
        ](auto const& product)
        {
            return product->getName() == product_name;
        }
        );

//if we have found our product, we remove it...
        if (to_remove != productList.end())
        {
            productList.erase(to_remove);
        }
    }


    // return a const reference to the productList, this way we can iterate 
    // over the lists from outside the class without modifying it.
    std::vector<std::unique_ptr<Product>> const& getProductList() const
    {
        return productList;
    }

    // add other methods, like getTotalPrice() etc...
};

At first, the solution might seem a bit overwhelming since it's so different from C, but once you familiarize yourself with the STL and these more advanced constructs (such as lambdas) you will be writing safer code, faster.

from here, an example of usage of this class can be:

#include <iostream>

int main()  
{
    Cart cart;

    cart.addProduct(std::make_unique<Product>(10, "Apple"));
    cart.addProduct(std::make_unique<Product>(20, "Banana"));
    cart.addProduct(std::make_unique<Product>(30, "Orange"));

    cart.removeProduct("Banana");
//modern range based for loop on the returned const reference
    for(auto const& product : cart.getProductList())
    {
        std::cout << product->getName() << " " << product->getPrice() << std::endl;
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

3 Comments

The unique_ptr should be taken with a grain of salt here. It's not clear from the OP's question if Product instances need to exist only in distinct shopping carts, or all carts can share from those instances.
Certainly if the there are multiple Carts that pick Products from an inventory, it could benefit from using std::shared_ptr instead, from OP's question the use-case is unclear so I defaulted to the *_ptr with less overhead.
Better let the OP clarify 1st, before investing time in writing answers. If they clarify, there are loads of duplicates available here for the real underlying problems.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.