Why do all vector types have to be homogeneous even when using templates. I have tried having multiple types from the same base class in a single vector but I get errors. The only technique that seems to work is the following method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vector<Object*> items;
Knife knife;
Gun gun;
BaseballBat bat;
items.push_back(&knife);
items.push_back(&gun);
items.push_back(&bat);
for(int i = 0; i < items.size(); i++)
items[i]->displayContents();
Is there a way to do the following with templates? When I attempt to implement with templates I get a error informing me that the base class that I am trying to use only has a virtual function without a definition.
Polymorphism only works with pointers and references (and you can't have a vector of references).
The error you're getting is because Object is an abstract class, as it probably should be. But even if you made Object non-abstract, you still wouldn't be able to put heterogeneous objects in a vector.
So, in other words, yes. The only way to have a heterogeneous vector is to make it an std::vector<PolymorphicBase *> and store pointers to derived classes.
Either that, or use a variant type, such as boost::any, or QVariant from Qt. Personally, I prefer to avoid variant types if I can.
So the first relevant bit of information: you can't have a vector of references. References aren't assignable.
Pointers are the easiest way to handle dynamic containers of polymorphic objects, in your second example you could change to a T* in the vector type and just reference the address in addItem (this presents some major potential headaches with memory management, but it's valid)
The second way to handle this would be allow your objects to be assignable and allow the Items class to make a duplicate that it will store in your collections variable. Which is very likely what you're attempting to do and precisely why it's complaining at you. If you simply pass an Object reference (which can be polymorphic) and it attempts to copy that object into the vector, it has no guarantee that you're not going to pass a generic Object, which is impossible because you haven't implemented some of the virtual methods. (also keep in mind with the second example your vector is exactly this: vector<Object> collections, not vector<Object&> collections, because that's impossible as I mentioned)
The compiler is intelligent, and the language is flexible, but sometimes the finer points are a bit of a balancing act.
In my head, it is almost as if you are declaring the same object multiple times. Since, the vector (with vector<Object*>), is pointing at the same object. Why is it making copies still? Isn't the point of using a vector of pointers to eliminate copies being produced?