我和几个同事一起练习C++的时候,其中一个人在派生类中 "经历了一个bug"。长话短说,他在调用基类方法(callFoo
),他还以为是在打电话 A::Foo()
但他得到了 B::Foo()
而不是。
这里有一个完整的例子,说明我其实是在问什么。我真的不知道怎么解释比这更好。我确实找到了一个解决方案,但是这个解决方案很尴尬,它使得代码有点难以 "消毒",以便于我们未来类的扩展。有没有其他的解决方案?(也许是一个关键字?)
n.b.这个例子纯粹是演示性的:在原来的例子中。callFoo()
是的 operator=
对于 Class A
. 我尽量把它简化。
例1:不受欢迎的行为
#include <iostream>
class A{
public:
virtual void Foo(){
std::cout<<"A Foo\n";
}
virtual void callFoo(){
Foo();
}
};
class B: public A{
public:
virtual void Foo() override{
std::cout<<"B Foo\n";
}
};
int main(){
B mB;
mB.Foo();
mB.callFoo();
return 0;
}
例2:非理想的修复方法;还有其他的解决方案吗?
class A{
public:
virtual void Foo(){
std::cout<<"A Foo\n";
}
virtual void callFoo(){
A::Foo();
}
};
很明显,你正在创建一个派生类的对象,并试图调用存在于基类中的callFoo()函数.我将尝试一步一步地可视化这个问题。
因此,我们需要明确地告诉编译器,我们需要基本版本的方法,并使用 A::Foo() 来调用Base类方法。
关于VTable和VPtr的更多细节,在stack-overflow中有一个有用的链接。VPtr和VTable的深度C++