On 2007-10-22 15:19, Bo Yang wrote:
Greg Herlihy :
I can understand static_cast, reinterpret_cast and const_cast, they
all work at compile time. But I can figure out how the C++'s dynamic-
cast works? Could you please explain how for me?
Thanks in advance!
Regards!
Bo
Consider this case:
class A{virtual ~A(){};};
class B
ublic A{};
A*a=new B;
B*b =dynamic_cast<B*>(a);. .
B* Dynamic_Cast(A*a ){
if(*((a->vptr)+1)()==B_RTTI())
return a;
return 0;
}
This implementation might work for typeid - because typeid has to
confirm only that type of the object being tested - matches the
specified type exactly.
A dynamic_cast operator however has to perform a much more complicated
test: whether an object (of unknown thype) is related to another type.
And to make do with a lot less information about the classes involved
than existed in the example above. For example:
struct A
{
virtual ~A() {}
};
bool TestA(void *p)
{
assert( p != NULL);
return dynamic_cast<A*>(p) != NULL;
}
Note that no derived classes of A (if any exist) are visible when this
source file is compiled. So no matter how many large or complex this
program's class hierarchy might be, dynamic_cast<> has only the "A"
class declaration with which to work here.
So how is dynamic_cast<> supposed to figure out whether p points to a
type that is somehow related to A? Well, given these constraints,
there is only one way to solve this problem. dynamic_cast must search
p's class hierarchy (essentially, discovering its layout as it goes
along) and to continue the search until either a A class is located
with the hierarchy - or there are no other classes left in the
hierarchy that need to be checked.
So, how C++ go along the classes hierarchy at runtime? RTTI? Is RTTI a
standard of C++? I think RTTI is not a standard part of C++!
RTTI is part of the C++ standard, do not confuse it with reflection
though. One way to accomplish this (though I do not think that is how it
is done) would be to add a second pointer (in addition to the vtable)
which points to a type object looking something like this:
class Type
{
char name[];
Type* super[];
Type* derived[];
};
That way typeid could (conceptually) be implemented something like this:
template<typename T>
type_info typeid(T t)
{
return type_info(t->typePtr->name)
}
And using some simple tree walking algorithms you can find out if a type
is in the same type-hierarchy as another.