【问题标题】:C++ type informationC++ 类型信息
【发布时间】:2012-07-13 19:37:25
【问题描述】:

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

【问题讨论】:

  • 请阅读一本好的 C++ 书籍(如《C++ 编程语言》),忘记您对 Java 的大部分了解。 C++ 编程与 Java 编程有很大不同。

标签: c++ polymorphism typeinfo


【解决方案1】:

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

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

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

pointer-to-vtable slot 意味着如果一个类(或其基类)有虚方法,那么sizeof 将大于对象成员字段的总和。

【讨论】:

    【解决方案2】:

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

    请注意,vtable 的使用不是 C++ 标准强制要求的,但在实践中几乎是通用的。

    【讨论】:

    • 另外,请注意,您无法在运行时获得任何有关 C++ 对象的重要类型信息。
    • @DeadMG,我试图暗示这一点,但我想我说得不够强烈。在 C++ 中定义多态性的方式非常有限。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      你问的是 reflection,不,C++ 没有它,而且它不是故意的。 Stroustrop 看到了其他语言,其中对象不断地用“你是什么”类型的消息相互询问,作为某种破坏的标志。偶然地,通过元编程可以获得有限的反射。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-27
        • 1970-01-01
        • 2021-08-20
        • 2019-03-03
        • 2010-10-21
        • 1970-01-01
        • 2017-06-22
        • 2019-04-15
        相关资源
        最近更新 更多