2012-07-13 87 views
1

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

+2

请获得一本好的C++书(如C++编程语言),并忘记了解Java的大部分知识。 C++编程与Java编程完全不同。 – 2012-07-13 19:42:43

回答

2

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

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

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

指针到虚表时隙意味着,如果一个类(或它的基类)具有虚拟方法,那么sizeof会比对象构件字段的总和。

2

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

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

+0

另外,请注意,在运行时您无法获取任何有关C++对象的重要类型信息。 – Puppy 2012-07-13 19:45:55

+0

@DeadMG,我试图暗示,但我想我没有足够强烈地说。多态性在C++中定义的方式使其非常有限。 – 2012-07-13 19:51:36

0

你在问关于反射,不,C++没有它,它并不是故意的。 Stroustrop看到了其他语言,在这些语言中,对象一直在用“你是什么”类型的信息来查询对方,以此来断定某些事情。意外的是,通过元编程可以获得有限的反射。

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

1

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