Not sure what you mean. Sounds like you store the objects by value, and you you have an array of Base
. That won't work, because as soon as you assign a Derived, that object will be converted to a Base, and the Derived part of the object is sliced away. But i think you want to have a array of pointers to base:
Base * bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i] = new Derived1;
else if(r == 1)
bases[i] = new Derived2;
// ...
}
If you ever haved worked with pointers, you will know it's a pain in the ass to manage them, espacially pass around and not lose them, since you will need to call delete on them to free the memory and call the destructor of the objects. You can use shared_ptr, and it will manage that for you:
shared_ptr<Base> bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i].reset(new Derived1);
else if(r == 1)
bases[i].reset(new Derived2);
// ...
}
Now, you can pass bases[x]
to another shared_ptr, and it will note you have got more than one reference - it will call automatically delete if the last reference to the objects go out of scope. Ideally, you would also replace the raw array by std::vector:
std::vector< shared_ptr<Base> > bases;
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases.push_back(shared_ptr<Base>(new Derived1));
else if(r == 1)
bases.push_back(shared_ptr<Base>(new Derived2));
// ...
}
Then you can pass the vector around, and don't lose the size of it, and you can dynamically add items to it on demand. Get the size of the vector using bases.size()
. Read about shared_ptr
here.
Conversion from a Base class to a Derived class should only be done when absolutely necessary. Normally, you want to use a technique called polymorphism
, which means you call a function on the base pointer, but it will actually call a function defined in the derived class, having the same signature (name and parameters are the same type) and is said to override
it. Read the article on wikipedia about it. If you really need to cast, you can do it like this for a raw pointer:
Derived1 * d = &dynamic_cast<Derived1&>(*bases[x]);
Using dynamic_cast ensures, that when you cast to the wrong type (i.e the type you cast is not the type that was created and assigned to the base pointer), you get an exception thrown by the operator. For the shared_ptr case, there are ways too:
shared_ptr<Derived1> d = dynamic_pointer_cast<Derived1>(bases[x]);
if(d) {
// conversion successful, it pointed to a derived. d and bases[x] point still
// to the same object, thus share it.
}