我试图模拟vptr/vtable概念。我有3个问题要问:
1. I没有为类FOO定义任何构造函数,它应该很好,就像在内部所看到的那样(Foo *ptr= new FOO是OK的)。但是,当我在堆上为FooVtable::bar()中的同一个对象创建对象时,它会抱怨没有找到适当的默认构造函数。为什么?
2. --我看到vptr指向某个地址(即使没有为vptr执行new FooVTable,我猜默认情况下是这样的。),FooVtable::bar正在被调用,但cout没有打印语句。为什么?
3. i(),我在打电话给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;
}发布于 2015-10-07 03:30:05
对于试图在类被完全声明之前使用类的情况,这是一个错误消息。在不同的编译器上,消息可能更像是"error:无效使用不完整类型'class Foo'“。
解决这一问题的一种方法是将完整的struct Foo内容放在FooVtable之上,然后使用FooVtable的前向声明而不是Foo。
vptr未初始化。像指针这样的基元类型不会被new初始化为任何类型的默认值。所以里面的东西都是垃圾。人们对此寄予厚望。
通过带有垃圾值的指针调用函数之后发生的任何事情都是未定义的行为。所以几乎任何事情都有可能发生,而且也不会有保证的解释。
然而,在这种情况下,还有另一个问题:您做了一个错误。cout<"FooVTable : bar";只有一个<,因此可以做一个奇怪和无用的比较,而不是输出任何东西。
指向成员函数的指针是可能的。在到目前为止所创建的情况下,您可能会使用一个。但是,一旦您开始将继承引入到场景中(这是虚拟函数最终有用的地方),尝试在不同类型之间解决这个问题可能会变得很有趣。(我很少使用成员函数指针,所以不能直接说。)
我的方法是对的,还是有更好的方法来解决这个问题?
它实际上取决于您试图“模拟”的实际实现的多少,以及您希望通过它实现什么。
https://stackoverflow.com/questions/32983035
复制相似问题