虚拟表指针和虚拟表模拟

时间:2015-10-07 02:53:45

标签: c++

我正在尝试模拟vptr / vtable概念。关于以下内容我有3个问题:

1。我没有为类 FOO 定义任何构造函数,这应该没问题,因为在main(Foo *ptr= new FOO中可以看到)。 但是当我在堆上为FooVtable :: bar()内部创建相同的对象时,它会抱怨找不到合适的默认构造函数。为什么呢?

2. 我看到vptr指向某个地址(即使vptr没有new FooVTable,我猜ctor默认是这样的。是否可以预期?),{ {1}}被调用,但cout不打印该语句。为什么呢?

3。 callsomeFun()内,我正在呼叫FooVtable::bar。我想在这里实现的是 foo->vptr->bar foo-> vptr-> bar 的一部分实际应该调用指向成员函数 Foo :: bar()的指针,我猜这是不可能的,因此我声明vptr->bar在其中我想通过ptr调用void bar(Foo* foo)。我正在接近它,还是有更好的方法来解决这个问题?

Foo:bar

1 个答案:

答案 0 :(得分:1)

  
      
  1. 当我在堆上为FooVtable :: bar()内部创建对象时,它抱怨找不到合适的默认构造函数。为什么?
  2.   

对于您在完全声明之前尝试使用类的情况,这是一个糟糕的错误消息。在不同的编译器上,消息可能更像是"错误:无效使用不完整类型'类Foo'"。

解决问题的一种方法是将完整的struct Foo内容放在FooVtable之上,然后使用FooVtable而不是Foo的前向声明。

  
      
  1. 我看到vptr指向某个地址(即使没有为vptr做新的FooVTable,我猜ctor默认情况下会这样做。是否可以预期?),FooVtable :: bar被调用但是cout没有打印语句。为什么?
  2.   

vptr未初始化。像指针这样的原始类型只能通过new初始化为任何类型的默认值。所以无论在哪里都有垃圾。预计会有这么多。

通过具有垃圾值的指针调用函数后发生的任何事情都是Undefined Behavior。所以任何事情都可能发生,并且不会有保证的解释。

然而,在这种情况下,还有另一个问题:你犯了一个错字。 cout<"FooVTable : bar";只有一个<,因此会进行奇怪而无用的比较,而不是输出任何内容。

  
      
  1. foo-&gt; vptr-&gt; bar应该实际调用指向成员函数Foo :: bar()的指针,我猜这不可能直接使用
  2.   

指向成员函数的指针是可能的。在目前为止您创建的情况中,您可能会使用一个。然而,一旦你开始将继承带入场景(虚拟函数最终有用的地方),尝试在不同类型之间进行这项工作可能会很有趣。 (我使用成员函数指针很少,以至于我不能随便说。)

  

我接近它是对,还是有更好的方法来解决这个问题?

这实际上取决于您尝试过多少真正的实施模拟&#34;以及你希望通过它实现的目标。