Arrays of pointers to classes and type casting

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?

Thanks
Last edited on
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.
Last edited on
Why don't you use a vector?
std::vector<Base*> b(len);
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 = new Base*[len];
+1 to Peter87.

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:

1
2
for (int i=0; i<=len;++i)
   b[i]=new Derived();


No casting needed as I wished!

Thanks all.

Topic archived. No new replies allowed.