Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
As you saw in the earlier program that used the hierarchy of
Security classes, dynamic_cast can detect both exact types and, in an inheritance hierarchy with multiple levels, intermediate types. Here is
another example.
//: C08:IntermediateCast.cpp
#include <cassert>
#include <typeinfo>
using namespace std;
class B1 {
public:
virtual ~B1() {}
};
class B2 {
public:
virtual ~B2() {}
};
class MI : public B1, public B2 {};
class Mi2 : public MI {};
int main() {
B2* b2 = new Mi2;
Mi2* mi2 =
dynamic_cast<Mi2*>(b2);
MI* mi = dynamic_cast<MI*>(b2);
B1* b1 =
dynamic_cast<B1*>(b2);
assert(typeid(b2) != typeid(Mi2*));
assert(typeid(b2) == typeid(B2*));
delete b2;
} ///:~
This example has the extra complication of multiple
inheritance (you ll learn more about multiple inheritance later in this chapter,
and in Chapter 9). If you create an Mi2 and upcast it to the root (in this case, one of the two possible roots is chosen), the dynamic_cast
back to either of the derived levels MI or Mi2 is successful.
You can even cast from one root to the other:
B1* b1 = dynamic_cast<B1*>(b2);
This is successful because B2 is actually pointing to
a Mi2 object, which contains a subobject of type B1.
Casting to intermediate levels brings up an interesting
difference between dynamic_cast and typeid. The typeid operator always produces a reference to a static type_info object that describes the dynamic type of the object. Thus, it doesn t give you
intermediate-level information. In the following expression (which is true),
typeid doesn t see b2 as a pointer to the derived type, like dynamic_cast
does:
typeid(b2) != typeid(Mi2*)
The type of b2 is simply the exact type of the
pointer:
typeid(b2) == typeid(B2*)
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |