当我将虚拟方法定义为私有时会发生什么?
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::virtualMethod
是 classB
处的一个私有方法,因此,我们不会从 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 有一个名为 mB
、virtual
或其他方法的方法,因此无法通过该指针访问它。
成员名称可见性基于对象或指针的声明类型。由于 obj
被声明为 ClassA*
类型,因此只有 ClassA
中的成员名称可见。在 class 之外,只有 public 成员可见。
这是因为指向 ClassA
的指针可以指向基 class 或其任何派生 class 的对象。允许您调用 obj->mB()
是没有意义的,因为 obj
实际上可能不指向具有 mB()
成员函数的对象。我们必须能够在编译时确定名称是否有效,而这只能取决于类型声明,而不是值。
虚拟方法的规则仅在 允许可见性后发挥作用。当通过指针调用虚方法时,它使用它指向的对象的 actual 类型来找到要调用的方法。在运行时,它沿着派生树向上查找定义该方法的派生程度最高的 class,并使用它。
给定以下代码:
#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::virtualMethod
是 classB
处的一个私有方法,因此,我们不会从 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 有一个名为 mB
、virtual
或其他方法的方法,因此无法通过该指针访问它。
成员名称可见性基于对象或指针的声明类型。由于 obj
被声明为 ClassA*
类型,因此只有 ClassA
中的成员名称可见。在 class 之外,只有 public 成员可见。
这是因为指向 ClassA
的指针可以指向基 class 或其任何派生 class 的对象。允许您调用 obj->mB()
是没有意义的,因为 obj
实际上可能不指向具有 mB()
成员函数的对象。我们必须能够在编译时确定名称是否有效,而这只能取决于类型声明,而不是值。
虚拟方法的规则仅在 允许可见性后发挥作用。当通过指针调用虚方法时,它使用它指向的对象的 actual 类型来找到要调用的方法。在运行时,它沿着派生树向上查找定义该方法的派生程度最高的 class,并使用它。