请看下面的代码 list :
#include <iostream>
using namespace std;
class Base {
public:
virtual void Message() = 0;
};
class Intermediate : public Base {
};
class Final : public Intermediate {
void Message() {
cout << "Hello World!" << endl;
}
};
int main() {
Final final;
/* Wont work (obviously):
Final* finalPtr = &final;
finalPtr->Message();
*/
// Works:
Intermediate* finalPtr = &final; // or Base* finalPtr = &final;
finalPtr->Message();
return 0;
}
注意以下事项:
- 在抽象Base类中,纯虚函数message()是public
- Intermediate 类(也是抽象的)继承自 Base 类(Does message() function remain public pure virtual in Intermediate?)
- Final 类继承自Intermediate 类并且message() 函数是私有(private)的(默认情况下)
- 在 main 中,创建了一个 Final 类型的对象
- 创建了一个指向Final对象的Intermediate指针
问题: 如果您运行该程序,行 finalPtr->Message(); 成功调用 Final 的 message() 函数实现强>私有(private)强>。这是怎么发生的?基类是否覆盖或忽略派生类的访问限制?
相关问题: 关于上面的 (2.),定义 Intermediate 类的正确方法是什么?是否需要从基类中重新声明纯虚函数 message() 并牢记 Intermediate 类并非旨在提供实现。
注意:代码已通过 Digital Mars Compiler (dmc) 和 Microsoft 的 Visual Studio Compiler (cl) 进行了测试,并且在两者中都运行良好
最佳答案
How does that happen? Does a base class override or ignore a derived class' access restrictions?
通过公共(public)继承,基类的所有公共(public)成员都成为派生类的公共(public)成员。所以是的 Message()
是 Intermediate
中的公共(public)函数。
该函数在基类(中间
)指针上调用,该函数在基类中是公共(public)的。动态调度(即对 Derived 类函数的实际调用)仅在运行时发生,因此有效。
以上是由于在运行时,访问说明符没有意义,访问说明符规则只在编译时解析和生效。
如果您在派生类指针上调用该函数,那么在编译时编译器会检测到 Message()
在 Final
中被声明为 private
因此它给出了错误。
从抽象类派生时,派生类必须为所有基类的纯虚函数提供定义,否则将导致派生类也是一个抽象类。
这里的 Intermediate
类是一个抽象类,只要你不需要创建这个类的对象,它就可以正常工作。请注意,您可以创建指向抽象类的指针。
关于c++ - 多态性和数据隐藏 : Does a base class override or ignore a derived class' access restrictions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25926947/