When you write mylist.push_back(myB)
, a slice occurs. The mylist
stores A
objects. So what happens is that your B
is converted to an A
, losing all of the things that are in B
and not A
. Just the A
is stored. You cannot retrieve the lost pieces.
It is the same as doing:
B myB(5);
A a(myB);
In order to have polymorphic behaviour, you need to make A
be a polymorphic class, and also refer to the objects by pointers, i.e. A *
.
So you need to add at least one virtual function to A
(virtual destructor would be a good idea), and have your vector store pointers. For example:
std::vector< A* > mylist;
mylist.push_back( new myB(5) );
B *instance = dynamic_cast<B *>(mylist[0]);
Now, this code is OK but you have to be very careful about deleting memory you new'd. To solve that for you there is shared_ptr
which is a ref-counted pointer. I made the following test case which seems to work (disclaimer - I'm not an expert in polymorphism with smart pointers, so I hope there is not a stealthy error here)
#include <iostream>
#include <memory>
#include <vector>
class A
{
public:
A(){};
virtual ~A() {}
};
class B : public A
{
public:
B(int value): foo(value) {}
int foo;
~B() { std::cout << "Destructor B(" << foo << ")" << std::endl; }
};
int main()
{
std::vector< std::shared_ptr<A> > mylist;
// Test the polymorphic behaviour
// mylist.push_back( std::make_shared<A>() );
// create directly into container
mylist.push_back( std::make_shared<B>(5) );
// via pointer
B *temp_b = new B(6);
mylist.push_back( std::shared_ptr<B>(temp_b) );
std::shared_ptr<B> instance = std::dynamic_pointer_cast<B>( mylist[0] );
if ( !instance )
std::cout << "Item was not a B" << std::endl;
else
std::cout << instance->foo << std::endl;
}