问题
I know that following code gives compilation error :
class A{ public : virtual void name(){cout<<typeid(this).name()<<endl;}; };
class B:protected A{public : virtual void name(){cout<<typeid(this).name()<<endl;};};
void foo(B* b)
{
A * a = dynamic_cast<A*>(b); //Error : 'A' is an inaccessible base of 'B'
return;
}
But then why in the C++ Stroustrup book (15.4.1) he writes
class BB_ival_slider:public Ival_slider,protected BBslider{ //...
};
void f(BB_ival_slider*p)
{
// ok
BBslider* pbb2 = dynamic_cast<BBslider*>(p); // ok: pbb2 becomes 0
}
Shouldn't the line be compilation error ? So either my gcc is wrong in flagging it as compilation error OR the unthinkable, stroustrup typo or most plausibly I have missed something...
回答1:
The actual quote from 15.4.1 is:
class BB_ival_slider : public Ival_slider, protected BBslider { // ... }; void f(BB_ival_slider* p) { Ival_slider* pi1 = p; // ok Ival_slider* pi2 = dynamic_cast<Ival_slider*>(p); // ok BBslider* pbb1 = p; // error: BBslider is a protected base BBslider* pbb2 = dynamic_cast<BBslider*>(p); // ok: pbb2 becomes 0 }
That is the uninteresting case. However, it is reassuring to know that
dynamic_cast
doesn't allow accidental violation of the protection of private and protected base classes.
So it would seem that the text describing the code is correct, but for the wrong reasons -- dynamic_cast
doesn't allow accidental violation of the protection of private and protected base classes, but only because using it would be ill-formed and will result in a compiler error, not because using it will yield a null-pointer. And, of course, the code the text is describing is definitely incorrect.
Mistakes happen -- maybe it will be fixed in the 4th edition of the book. :-]
(Also, note that if BB_ival_slider
declares f
to be a friend
, then the code will behave as described in the book. Perhaps this friend
declaration was implied earlier in the chapter, but I don't have time right now to read over it carefully to check one way or the other.)
回答2:
Perhaps he tested that code, perhaps not. (Lots of authors put untested code in their books.) If he did test it, keep in mind that not all compilers are created equal. g++ fails with error: 'BBslider' is an inaccessible base of 'BB_ival_slider'
. clang fails with error: cannot cast 'BB_ival_slider' to its protected base class 'BBslider'
. Other compilers: Who knows? Every compiler I know of has some problem with compliance with the standard.
回答3:
I think if I am not finding any constructive evidence then I might just say
"Stroustrup was wrong" (that sounds scary :( )
I dont think compilers are allowed to spill the guts of class internal willingly(by defined standard). Unless they are put through knife. (evil pointer operation that is)
来源:https://stackoverflow.com/questions/7210321/dynamic-cast-doubt-from-c-stroustrup-converting-to-protected-base-class