有没有另一种方法可以防止派生方法被调用 superclass 而不是 base class 方法,比如使用关键字或其他方法?
Is there another way to prevent a derived method from superclass being called instead of the base class one, like with a keyword or something?
当我和我的一些同事一起练习 C++ 时,其中一位 "experienced a bug" 在派生的 class 中。长话短说,他正在调用基本方法 (callFoo
),他希望调用 A::Foo()
,但他却调用了 B::Foo()
。
这是我实际要求的完整示例。我真的不知道如何解释比这更好。我确实找到了解决方案,但该解决方案很尴尬;对于我们 classes 的未来扩展,它使得代码有点难以 "sanitize"。还有其他解决方案吗? (也许是关键字?)
n.b。该示例纯粹是说明性的:在原始示例中,callFoo()
是 Class A
的 operator=
。我尽量简化了。
示例 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();
}
};
很明显,您正在创建 Derived class 的对象并试图调用基 Class 中存在的 callFoo() 函数。
我会尝试一步一步地想象这个:
- B mB ---> 由于我们正在创建 Derived class 的 对象,因此 VPtr 将指向到 Derived Class.
的 Vtable
- mB.callFoo(); ---> Vptr 仍然指向 Derived class.Since 对象的 VTable 试图调用 callFoo() ,它未在 Derived Class 的 VTable 中找到条目。它调用 Base Class 的 callFoo()。 现在是主要问题,Foo() 是从 callFoo() 的主体中调用的,但同样如前所述,它将在 VTable 中搜索此函数的条目 Derived Class 因此它将调用 Derived class Foo().
因此我们需要明确地告诉编译器,我们需要该方法的基础版本并使用 A::Foo() 来调用基础 class 方法。
有关 VTable 和 VPtr 的更多详细信息,堆栈溢出中有一个有用的 link:
VPtr And VTable In Depth C++
当我和我的一些同事一起练习 C++ 时,其中一位 "experienced a bug" 在派生的 class 中。长话短说,他正在调用基本方法 (callFoo
),他希望调用 A::Foo()
,但他却调用了 B::Foo()
。
这是我实际要求的完整示例。我真的不知道如何解释比这更好。我确实找到了解决方案,但该解决方案很尴尬;对于我们 classes 的未来扩展,它使得代码有点难以 "sanitize"。还有其他解决方案吗? (也许是关键字?)
n.b。该示例纯粹是说明性的:在原始示例中,callFoo()
是 Class A
的 operator=
。我尽量简化了。
示例 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();
}
};
很明显,您正在创建 Derived class 的对象并试图调用基 Class 中存在的 callFoo() 函数。 我会尝试一步一步地想象这个:
- B mB ---> 由于我们正在创建 Derived class 的 对象,因此 VPtr 将指向到 Derived Class. 的 Vtable
- mB.callFoo(); ---> Vptr 仍然指向 Derived class.Since 对象的 VTable 试图调用 callFoo() ,它未在 Derived Class 的 VTable 中找到条目。它调用 Base Class 的 callFoo()。 现在是主要问题,Foo() 是从 callFoo() 的主体中调用的,但同样如前所述,它将在 VTable 中搜索此函数的条目 Derived Class 因此它将调用 Derived class Foo().
因此我们需要明确地告诉编译器,我们需要该方法的基础版本并使用 A::Foo() 来调用基础 class 方法。
有关 VTable 和 VPtr 的更多详细信息,堆栈溢出中有一个有用的 link: VPtr And VTable In Depth C++