有没有其他方法可以防止派生方法被调用超类而不是基类,比如用关键字之类的



当我和一些同事练习C++时,其中一位同事在派生类中"遇到了一个错误"。长话短说,他正在调用基本方法(callFoo(,他本想调用A::Foo(),但他却得到了B::Foo()

下面是一个完整的例子,说明我实际在问什么。我真的不知道该怎么解释才能比这更好。我确实找到了一个解决方案,但这个解决方案很尴尬;这使得代码很难为我们类的未来扩展进行"清理"。是否有其他解决方案?(也许是关键词?(

n.b.这个例子纯粹是示范性的:在最初的例子中,callFoo()Class Aoperator=。我尽力简化它。

示例1:不希望的行为

#include <iostream>
class A{
public:
virtual void Foo(){
std::cout<<"A Foon";
}
virtual void callFoo(){
Foo();
}
};
class B: public A{
public:
virtual void Foo() override{
std::cout<<"B Foon";
}
};

int main(){
B mB;
mB.Foo();
mB.callFoo();
return 0;
}

示例2:非理想修复;还有其他解决方案吗?

class A{
public:
virtual void Foo(){
std::cout<<"A Foon";
}
virtual void callFoo(){
A::Foo();
}
};

很明显,您正在创建一个派生类的对象,并试图调用基类中的callFoo((函数。我将尝试一步一步地将其可视化:

  1. B mB-->由于我们正在创建派生类的对象,VPtr将指向派生类的Vtable
  2. mB.callFoo((;--->Vptr仍然指向派生类的VTable。由于对象正在尝试调用callFoo((,因此在派生类的VTable中找不到条目现在是主捕获,从callFoo((的主体调用Foo(

因此,我们需要明确地对编译器说,我们需要该方法的基本版本,并使用A::Foo((来调用基类方法。

有关VTable和VPtr的更多详细信息,堆栈溢出中有一个有用的链接:VPtr和VTable深度C++

最新更新