C ++类型信息

时间:2012-07-13 19:37:25

标签: c++ polymorphism typeinfo

我正在从java迁移到cpp,我在理解一些cpp功能如何工作时遇到了一些问题。当我们使用多态或类型安全的转换时,cpp需要知道对象的确切类型。在java中,每个对象都有一个指向其定义类的链接,因此可以检索此信息。但是在cpp中并非如此(我认为),我说这是因为sizeof()运算符返回的内容不超过对象字段占用的内容,因此我猜测不是存储类型信息的位置。 我错了吗?如果没有那么cpp如何管理多态和东西?

4 个答案:

答案 0 :(得分:2)

C ++多态性仅限于虚函数。实现虚函数所需的全部是一个类通用的函数指针表,通常称为 vtable 。指向vtable的指针将添加到每个对象中,但vtable本身对于同一类的所有对象都是通用的。

请注意,使用vtable不是C ++标准规定的,但在实践中几乎是通用的。

答案 1 :(得分:2)

C ++只能对具有虚方法的类型执行动态类型内省;与Java不同,默认情况下C ++方法是非虚拟的。

向类添加虚方法的(通常)结果是编译器在类结构中发出一个附加的隐藏槽,其中包含指向 vtable 的指针; vtable包含用于虚方法的方法指针的槽和用于动态类型信息的附加指针。 vtable以下列方式使用:

  • 在实例上调用虚方法将遵循vtable并通过相应的vtable方法插槽调用;
  • 使用虚方法在类的实例上调用typeid将遵循vtable指向动态类型信息的指针,确定实例的实际(动态)类型;
  • 使用虚方法在类的实例上调用dynamic_cast将遵循vtable指向动态类型信息的指针,并使用它来调整实例指针;这是必要的,因为C ++允许多重继承,因此同一对象的不同类型的指针可能指向内存中的不同位置。

指向vtable的指针槽意味着如果一个类(或其基类)具有虚方法,那么sizeof将大于对象成员字段的总和。

答案 2 :(得分:1)

在C ++中,不使用RTTI是一种很好的做法,您可以在不使用它的情况下编写非常大的应用程序。您应该知道对象的类型,并将它们转换为适当的类型。在Java中你可以使用if(obj instanceof ClassA){},但在C ++中你想要看到这样的代码,即使它可以写入。

答案 3 :(得分:0)

你问的是反射,不,C ++没有它,并且它不是故意的。 Stroustrop看到了其他语言,其中的对象不断用#34来查询;你是什么"各种消息作为破碎的标志。偶然的是,通过元编程可以获得有限的反射。

有一种方法可以解决C ++中缺乏反射的问题。动态转换为void *提供指向最派生对象的指针。所以现在你只需要理解那个指针。如果您有自己的类型管理系统,则可以执行此操作。它并不简单,它几乎不可避免地破坏了某处的语言规则,但它常常用于检查点/重启目的。