向下转换具有非多态类型的层次结构

时间:2011-01-31 02:46:41

标签: c casting struct

这完全是在C。

假设您有一个基本结构和另外两个派生结构。这些派生的结构不是在经典意义上得出的(即:A:B),而是它们只包含基本类型的结构。因此,如果结构A是基础而B是2个派生结构之一,则B将具有类型A的成员。像这样:

struct A {
     // blah blah...
};

struct B {
     A part_a;
     // more stuff...
}

struct C {
     A part_a;
     // SO MUCH STUFF
}

假设你有一个功能,A_downcast_B,就像这样:

B * A_downcast_B(A * a)
{
     // downcast the A* here somehow
}

如果0无法成功下载到类型-1的结构中,您希望此函数返回'a'B。因此,例如,如果类型为C的'derived'结构具有类型为A*的指针,并且该指针已传递给此函数,则该函数将返回0,{ {1}}或-1

有办法做到这一点吗?我现在已经考虑了几个小时了,这让我很难过。

1 个答案:

答案 0 :(得分:8)

如果不在struct A中嵌入某种运行时类型信息,就不可能做到。例如,您可以存储指向某种类型信息的指针,并且必须在创建任何“派生”结构时进行初始化。

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;
}

请注意,这实际上只是C ++的dynamic_cast运算符的简化实现,它只适用于多态数据类型。这就是为什么运行时只能访问运行时类型信息,如果对象中嵌入了某种类型信息 - 它的vtable。