我正在尝试模拟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
答案 0 :(得分:1)
- 当我在堆上为FooVtable :: bar()内部创建对象时,它抱怨找不到合适的默认构造函数。为什么?
醇>
对于您在完全声明之前尝试使用类的情况,这是一个糟糕的错误消息。在不同的编译器上,消息可能更像是"错误:无效使用不完整类型'类Foo'"。
解决问题的一种方法是将完整的struct Foo
内容放在FooVtable
之上,然后使用FooVtable
而不是Foo
的前向声明。
- 我看到vptr指向某个地址(即使没有为vptr做新的FooVTable,我猜ctor默认情况下会这样做。是否可以预期?),FooVtable :: bar被调用但是cout没有打印语句。为什么?
醇>
vptr
未初始化。像指针这样的原始类型只能通过new
初始化为任何类型的默认值。所以无论在哪里都有垃圾。预计会有这么多。
通过具有垃圾值的指针调用函数后发生的任何事情都是Undefined Behavior。所以任何事情都可能发生,并且不会有保证的解释。
然而,在这种情况下,还有另一个问题:你犯了一个错字。 cout<"FooVTable : bar";
只有一个<
,因此会进行奇怪而无用的比较,而不是输出任何内容。
- foo-&gt; vptr-&gt; bar应该实际调用指向成员函数Foo :: bar()的指针,我猜这不可能直接使用
醇>
指向成员函数的指针是可能的。在目前为止您创建的情况中,您可能会使用一个。然而,一旦你开始将继承带入场景(虚拟函数最终有用的地方),尝试在不同类型之间进行这项工作可能会很有趣。 (我使用成员函数指针很少,以至于我不能随便说。)
我接近它是对,还是有更好的方法来解决这个问题?
这实际上取决于您尝试过多少真正的实施模拟&#34;以及你希望通过它实现的目标。