问题
CODE
struct A { }; // virtual details there, but left out
struct B { }; // virtual details there, but left out
struct C : A, B { }; // virtual details there, but left out
C c;
B& b = c;
A& a = dynamic_cast<A&>( b ); // will this cast succeed at run-time?
Note that I have left out the virtual details to keep the code simple.
If dynamic_cast<> is limited to direct casts along the inheritance hierarchy, then I expect the code above to fail at run-time (because B& is unrelated to A&).
However, if it is more generic/flexible, the code should work, because the true-type of the referred to object is of C type (and C can be referred to as B& or A&).
What do the C++ specifications say about this case?
回答1:
Right now, the code won't compile because none of the classes has any virtual functions -- a requirement to use dynamic_cast
. If you add at least one virtual function (e.g., a virtual dtor to B
, then yes, since a C
is derived publicly from B
, the cast will succeed.
Here's a bit of quick demo code:
#include <iostream>
struct A {
virtual void junk() { std::cout << "A"; }
void trash() { std::cout << "A"; }
virtual ~A() {}
};
struct B {
virtual ~B(){}
void trash() { std::cout << "B"; }
void junk() { std::cout << "B"; }
};
struct C : virtual A, virtual B {
void trash() { std::cout << "C"; }
void junk() { std::cout << "C"; }
};
int main() {
C c;
B& b = c;
A& a = dynamic_cast<A&>(b);
a.trash();
std::cout << "\n";
a.junk();
}
The output (with both VC++ and g++, and this isn't cutting edge, so I'd expect anything but a truly ancient compiler to get it right) is:
A
C
Showing that the a
has a static type of A
, but a dynamic type of C
.
回答2:
dynamic_cast<T>(v)
may go down to the most derived object of which v
is a sub-object, then up (possibly a different branch) to find an unambiguous base class to which T
is a pointer or a reference. From the standard:
5.2.7/8 If
C
is the class type to whichT
points or refers, the run-time check logically executes as follows:
- If, in the most derived object pointed (referred) to by
v
,v
points (refers) to a public base class subobject of aC
object, and if only one object of typeC
is derived from the subobject pointed (referred) to byv
the result points (refers) to thatC
object.- Otherwise, if
v
points (refers) to a public base class subobject of the most derived object, and the type of the most derived object has a base class, of typeC
, that is unambiguous and public, the result points (refers) to theC
subobject of the most derived object.- Otherwise, the run-time check fails.
来源:https://stackoverflow.com/questions/20015309/is-a-dynamic-cast-limited-to-direct-casts-along-the-inheritance-hierarchy