The solution to performing a correct and general C++ pointer cast is
to introduce a virtual method in the C++ application class whose instance
pointers are cast. This method (called )
receives a typeid argument t and returns the object itself (i.e.
its this pointer) correctly cast to the C++ type T corresponding
to t, if this can be cast to T i.e. t is a
base of this or NULL otherwise.
The implementation of
is as follows (in this example C is a C++ class having direct bases
A and B):
void* C::RTTI_cast(typeid t) { if (t == &RTTI_obj) return this; void* ptr; if (ptr=A::RTTI_cast(t)) return ptr; if (ptr=B::RTTI_cast(t)) return ptr; return 0; }
The idea behind
is to bypass C++'s pointer casting mechanism and to use a custom casting.
For this,
of a class is recursively calling the
methods of its bases. Moreover, all pointers are transmitted as void*'s
and NOT as typed C++ pointers.
Having the above, it is now very simple to implement PTR_CAST:
#define PTR_CAST(T,ptr) (T*)p->RTTI_cast(STATIC_TYPE_INFO(T))
The difference between this implementation of PTR_CAST and the one presented
in the previous section is obvious: now all the 'real' casting work is
done inside .
There is just one explicit C++ cast from void* to T* which is perfectly
safe since we're guaranteed that
returns a pointer of type T. Moreover, this version of
can obviously solve the virtual base problem and the casting across inheritance
paths problem. Finally, the run-time cost of the new
is basically identical to the old version. The only extra price to pay
is the declaration and definition of a new virtual in each C++ class (fortunately,
this process can be automated).