|
Thinking In C++. Volume 2: Practical ProgrammingIf 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 an 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 typeinfo 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*) void pointers RTTI only works for complete types, meaning that all class information must be available when typeid is used. In particular, it doesn’t work with void pointers: //: C08:VoidRTTI.cpp // RTTI & void pointers //!#include <iostream> #include <typeinfo> using namespace std; class Stimpy { public: В В virtual void happy() {} В virtual void joy() {} В virtual ~Stimpy() {} }; int main() { В void* v = new Stimpy; В // Error: //!В Stimpy* s = dynamic_cast<Stimpy*>(v); В // Error: //!В cout << typeid(*v).name() << endl; } ///:~ A void* truly means "no type information at all."[106]В Using RTTI with templates Class templates work well with RTTI, since all they do is generate classes ...» |
Код для вставки книги в блог HTML
phpBB
текст
|
|