当我将虚拟方法定义为私有时会发生什么?

What happens when I define a virtual method as private?

给定以下代码:

#include <iostream>

using std::cout;
using std::endl;

class classA {
    virtual void virtualMethod() {
        cout << "classA" << endl;
    }
public:
    virtual ~classA() {
        virtualMethod();
    }
    void mA() {
        virtualMethod();
    }
};

class classB: public classA {
    void virtualMethod() override {
        cout << "classB" << endl;
    }
public:
    ~classB() override {
        virtualMethod();
    }
    void mB() {
        virtualMethod();
    }
};
int main(void) {
    classA* obj = new classB;
    obj->mA();
    obj->mB(); // *** why I really get here error?
    delete obj;
    return 0;
}

我很乐意了解在主线中存在的任何行中发生的情况,此外,在 main 的最后 运行 中删除 obj 时发生了什么功能。我不想只知道答案: "the output is ...." ,而是要了解为什么会这样。

我的问题主要是了解我们在mA方法的情况。我们要去哪里?看来我们应该去 classA::virtualMethod,因为 classB::virtualMethodclassB 处的一个私有方法,因此,我们不会从 classA 遇到它(但是当我 运行 代码,我发现它不正确,我不明白为什么)。

此外,我很乐意理解为什么我在 obj->mB(); 行出错,根据编译器,原因是:

'class classA' has no member named 'mB'

但是为什么没有按照classB进行(毕竟我们做了new classB)。

class classB 中的私有 virtualMethod 可以通过 classA 中的任何函数访问,因为它在 classA 中标记为 virtual(请注意 Java 不允许这样做,但 C++ 允许)。

obj 是一个 classA 类型的指针。 classA not 有一个名为 mBvirtual 或其他方法的方法,因此无法通过该指针访问它。

成员名称可见性基于对象或指针的声明类型。由于 obj 被声明为 ClassA* 类型,因此只有 ClassA 中的成员名称可见。在 class 之外,只有 public 成员可见。

这是因为指向 ClassA 的指针可以指向基 class 或其任何派生 class 的对象。允许您调用 obj->mB() 是没有意义的,因为 obj 实际上可能不指向具有 mB() 成员函数的对象。我们必须能够在编译时确定名称是否有效,而这只能取决于类型声明,而不是值。

虚拟方法的规则仅在 允许可见性后发挥作用。当通过指针调用虚方法时,它使用它指向的对象的 actual 类型来找到要调用的方法。在运行时,它沿着派生树向上查找定义该方法的派生程度最高的 class,并使用它。