Down Casting a Hierarchy with Nonpolymorphic Types
This is strictly in C.
Say you're given one base struct, and 2 other derived structs. These derived structs are not derived in the classical sense (ie: A : B), rather, they only contain structs of the base type. So if struct A is开发者_开发百科 the base and B is one of the 2 derived structs, B would have a member of type A. Like this:
struct A {
// blah blah...
};
struct B {
A part_a;
// more stuff...
}
struct C {
A part_a;
// SO MUCH STUFF
}
Say you have a function, A_downcast_B, something like this:
B * A_downcast_B(A * a)
{
// downcast the A* here somehow
}
You want this function to return 0
or -1
if 'a'
could not be successfully downcasted to a struct of type B
. So for example, if a 'derived' struct of type C
had a pointer to it of type A*
, and that pointer were passed to this function, the function would return 0
, -1
or null
.
Is there a way to do this? I've been thinking about this for a few hours now and it's got me stumped.
It's impossible to do without embedding some sort of runtime type information in struct A
. For example, you could store a pointer to some sort of type information, and you must initialize that any time you create any 'derived' struct.
struct RTTI {
const char *typename;
// etc.
};
struct A {
const RTTI *rtti;
// rest of A
};
struct B {
A part_a;
...
};
const RTTI RTTI_B = {"B"};
struct C {
A part_a;
...
};
const RTTI RTTI_C = {"C"};
void make_B(B *b)
{
b->part_a.rtti = &RTTI_B;
// make the rest of B
}
void make_C(C *c)
{
c->part_a.rtti = &RTTI_C;
// make the rest of C
}
B * A_downcast_B(A * a)
{
return (a->rtti == &RTTI_B) ? (B*)a : NULL;
}
Note that this is really just a simplified implementation of C++'s dynamic_cast
operator, which only works with polymorphic data types. The reason that for that is that the runtime can only access the runtime type information if the object has some sort of type information embedded in it—its vtable.
精彩评论