我正在尝试模拟 vptr/vtable 概念。我有以下 3 个问题:
1. 我没有为类 FOO 定义任何构造函数,这应该没问题,正如在 main(Foo *ptr= new FOO
可以)。
但是,当我在 FooVtable::bar() 内部为相同对象在堆上创建对象时,它会提示找不到合适的默认构造函数。为什么?
2. 我看到 vptr 指向某个地址(即使没有 new FooVTable
为 vptr 完成,我猜 ctor 默认情况下会这样做。它是预期的吗?), FooVtable::bar
被调用但 cout 不打印语句。为什么?
3. 在 callsomeFun() 中,我正在调用 foo->vptr->bar
。我在这里想要实现的是 vptr->bar
部分 foo->vptr->bar实际上应该调用一个指向成员函数的指针 Foo::bar() ,我想这不是直接可能的,因此我在里面声明了 void bar(Foo* foo)
想通过 ptr 调用 Foo:bar
。我的做法是否正确,或者是否有更好的方法来解决这个问题?
class Foo;
struct FooVtable {
void bar(Foo* foo)
{
//Foo *ptr = new Foo; //Why does this throw error as No Default constructor?
cout<"FooVTable : bar"; //Doesnt get printed even though gets called
}
};
struct Foo {
FooVtable* vptr;
void bar(Foo *foo)
{
cout<<"Foo : bar";
}
};
int callSomeFun(Foo* foo) {
foo->vptr->bar(foo);
return 0;
}
int main()
{
Foo *ptr=new Foo;
callSomeFun(ptr);
return 0;
}
最佳答案
- when i create the object on heap for the same inside FooVtable::bar() , it complains about no appropriate default constructor found. Why?
对于您试图在一个类被完全声明之前使用它的情况,这是一个糟糕的错误消息。在不同的编译器上,消息可能更像是“错误:无效使用不完整类型‘class Foo’”。
解决它的一种方法是将完整的 struct Foo
上面的东西FooVtable
然后使用 FooVtable
的前向声明而不是 Foo
.
- I see that vptr points to some address(even though there is no new FooVTable done for vptr,i guess ctor by default does it. is it expected?), FooVtable::bar is getting called but cout doesnt print the statement. Why?
那个vptr
未初始化。像指针这样的原始类型不会被 new
初始化为任何类型的默认值。 .所以里面的东西都是垃圾。这是意料之中的事。
通过具有垃圾值的指针调用函数后发生的任何事情都是未定义行为。所以几乎任何事情都可能发生,并且没有一个有保证的解释。
但是在这种情况下还有另一个问题:您打错了字。 cout<"FooVTable : bar";
有一个 <
因此会进行奇怪且无用的比较,而不是输出任何内容。
- foo->vptr->bar should actually call a pointer to member function Foo::bar() , which i guess isnt directly possible
指向成员函数的指针是可能的。您可能会在目前创建的情况下使用一个。然而,一旦您开始将继承引入场景(这是虚函数最终有用的地方),尝试在不同类型之间解决这个问题可能会很有趣。 (我很少使用成员函数指针,所以我不能随便说。)
Am i approaching it right, or is there a better way to approach this?
这实际上取决于您尝试“模拟”的真实实现的程度以及您希望通过它实现的目标。
关于c++ - 虚拟表指针和虚拟表模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32983035/