Hi all,
I am interested in the cleanest way to declare an array of pointers to a base class and assign to it an array of pointers to a derived class. Consider the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
class Base{
int x;
};
class Derived:public Base{
float y;
int z;
};
int main(){
int len=10;
Base ** b;
//b= new Derived *[len]; //Does not work compile error
//b= (Base **)new Derived *[len];//works!
//b= static_cast<Base **>(new Derived *[len]); //does not work
//b= const_cast<Base **>(new Derived *[len]); //does not work;
//b= dynamic_cast<Base **>(new Derived *[len]); //does not work
b= reinterpret_cast<Base **>(new Derived *[len]); //works;
}
The traditional C-style cast works, and reinterpret cast also works. I don't understand why the static_cast does not work. And more importantly, following Myers's advice in Effective C++, how can I do this without casting?
It's conceptually flawed, which is why static_cast doesn't like it. Consider:
1 2 3 4
Derived* d = new Derived;
Base** b = &d; // <- luckily, this will error
*b = new Base; // perfectly legal, however it's fatal because now 'd' no longer points to a Derived
EDIT:
If you want to do it properly, you'd want this:
1 2
Derived* d = new Derived;
Base*const* = &d; // I believe this will be OK
EDIT 2: hmm, nope. I guess that doesn't work either.
But b is meant to be an array of pointers to objects. In the actual application I will have several derived classes, and only at run-time will I know which type of derived pointer each cell of the b array is going to point to.
The main point is that while I can have polymorphism in that for pointers to an object of Base class I can assign to them pointers to Derived objects, apparently this sort of polymorphism does not extend to arrays of pointers.
Again I know how to do this using C-style cast or reinterpret_cast. But need to know if there is a cleaner, preferably cast-free way.
b is an array of Base pointers, not an array of Derived pointers. Therefore you should be assigning it as such.
The main point is that while I can have polymorphism in that for pointers to an object of Base class I can assign to them pointers to Derived objects, apparently this sort of polymorphism does not extend to arrays of pointers.
I don't know if this helps clarify, but the way I think of it is that inheritance forms an "is a" relationship. Derived is a child of Base, therefore Derived "is a" Base.
This means a Base* can point to either a Base or a Derived, because they're both a Base.
On the other hand, Derived* is not derived from Base*, therefore a Derived* is not a Base*, and a Base** cannot point to a Derived** because they are two distinctly different types.
Thanks to Peter87 and also Disch. This solves the problem. After b=new Base*[len], I could allocate to each cell a pointer to a Derived without casting: