Here's a similar example, using polymophism:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
#include <iostream>
#include <vector>
using namespace std;
// abstract base class
class Animal
{
public:
// pure virtual method
virtual void speak() = 0;
// virtual destructor
virtual ~Animal() {}
};
// derived class
class Dog : public Animal
{
public:
// polymorphic implementation of speak
virtual void speak() { cout << "Ruff!"; }
};
int main( int argc, char* args[] )
// container of base class pointers
vector<Animal*> barn;
// dynamically allocate an Animal instance and add it to the container
barn.push_back( new Dog() );
// invoke the speak method of the first Animal in the container
barn.front()->speak();
// free the allocated memory
for( vector<Animal*>::iterator i = barn.begin(); i != barn.end(); ++i )
{
delete *i;
}
// empty the container
barn.clear();
return 0;
}
|
The reason for storing base class pointers is because the STL container will make its own copy of the object being inserted. If the container is of the base class, Automobile, it will only copy the base class portion of the object. If the container is of base class pointers, Automobile*, a pointer to the complete object will be stored.
The drawback (if you would call it that) to storing pointers is that memory management is now up to you. Using dynamically allocated memory will allow your container hold valid pointers, regardless of scope. For example, without dynamically allocating the object, the following issue exists:
1 2 3 4 5 6 7
|
//...
vector<Animal*> barn;
{
Dog spike; // spike is a local variable
barn.push_back( &spike );
} // from this point on, barn contains an invalid pointer
// because spike has gone out of scope
|
A better solution for memory management would be a smart pointer, also recommended by Abramus. For example, see
http://www.boost.org/doc/libs/1_41_0/libs/smart_ptr/shared_ptr.htm
One last note on the polymorphism. In the example above, the virtual methods could be regular methods if you do not need a different derived behavior. From the original post, it read as if the data members will differ but the behavior will remain the same.
Hope this helps.