A tweak on this question that I've run into. Consider:
class A {};
class B : private A {
static void foo();
};
void B::foo(){
B* bPtr1 = new B;
A* aPtr1 = dynamic_cast<A*>(bPtr1); // gives pointer
B* bPtr2 = dynamic_cast<B*>(aPtr1); // gives NULL
}
Since aPtr1
is, in fact, of type B*
, and since we've got full access to B
and its inheritance from A
, I'd expected both casts to work. But they don't; why? Is there another way to achieve this cast?
Note that:
- If
foo()
were not a member of B, both casts would fail. - If
B
inherits fromA
publicly, both casts would work.
They don't work because there's no virtual functions in A. When you do the downcast then that's trivial- the compiler probably doesn't even bother making a check. When you make an upcast then the compiler must check, but it's only defined to work when you have virtual functions. When you don't, then the compiler will fail to make the check and the result is
NULL
.The inheritance protection level and other accessibility issues are orthogonal to the problem, and they only exist at compile-time, if the program compiles then they work fine.
That's just not true.
foo()
has absolutely no bearing on RTTI functionality- it's not virtual and it's not even an instance member. If B inherits from A publicly- then A still has no virtual functions and it still won't work.5.2.7 (ISO/IEC 14882, 12/29/2003) is pretty explicit on this point:
(recall 11.2 "A base class is said to be accessible if an invented public member of the base class is accessible.").
This explains why the first cast works. Now, for the second:
So it seems that the behavior you observe is due to the
private
inheritance: even if the base class is accessible, it is not public, and the standard requires public, not accessible.Annoying, isn't it ? I don't have the C++0x draft handy, perhaps someone can edit my answer with quotes from it, in case things have changed.
It depends on what you want to do. Basically, private inheritance is just another device for performing composition. If you really are to return a pointer to the private derived instance, then either make the inheritance public, or return a member.
Anyways, you'll happy to know that
static_cast
doesn't seem to have this limitation:so if you know for sure what the actual dynamic type of the pointer is, you are allowed to
static_cast
insidefoo
.I'd be interested in any additional information about why this inconsistency exists.