有没有另一种方法可以防止派生方法被调用 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 Aoperator=。我尽量简化了。

示例 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() 函数。 我会尝试一步一步地想象这个:

  1. B mB ---> 由于我们正在创建 Derived class 的 对象,因此 VPtr 将指向到 Derived Class.
  2. Vtable
  3. 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++