Search code examples
c++inheritancepointersstlabstract-base-class

STL List - Datatype as a pointer object


I'm having a problem using inheritance and the STL list library...

Say, I have an abstract base class with two derived classes (where all comparison operators are defined). The list is declared as

list<StoreItem*> items;

I'm inserting a derived class (of the abstract base class, StoreItem) called either Food or Clothing. I make a new StoreItem pointer that's about to be inserted:

StoreItem* item = new Food(arguments here);

Now, I'm wanting to insert this new item (in order) to the list, and my attempt is this:

list<StoreItem*>::iterator iter;
for (iter = inventory.begin(); iter != inventory.end(); iter++)
{
    if (*item < **iter)
        break; // break out to insert
}

inventory.insert(iter, item);

Is there anything I'm doing wrong? Also, how would I pull the information from the inventory? (ex: Food tempFruit(**iter) using the copy constructor).

Thank you in advance! Have a good day.


Solution

  • You are assuming that the item you are pulling from the list is a Food instance; however, the compiler doesn't know that. When you construct a new instance of Food from an item in the list (an item with apparent type StoreItem), you are trying to call Food::Food(const StoreItem) or something compatible. Why? Because the iterator points to a StoreItem* that could be an instance of a StoreItem object, or an instance of any class derived from StoreItem, such as Food.

    As other posters have commented, polymorphism is a key to success. Do you really need to know that the item is a Food? If not, then access the interface shared by all store items (like price, serial-number, etc.). If you need to know something specific about the item, then you can try to infer its type:

    Food *food = dynamic_cast<Food*>(*iter);
    if (food != NULL) {
       // perform food related logic
       std::cout << "Ingredients: " << food->ingredients() << std::endl;
    }
    else {
       std::cout << "I can't eat that!" << std::endl;
    }