Mih*_*yan 13 c++ virtual inheritance access-specifier
# include <iostream>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "A::f()" << endl;
}
};
class B:public A
{
private:
virtual void f()
{
cout << "B::f()" << endl;
}
};
int main()
{
A *ptr = new B;
ptr->f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码正常工作并打印B :: f().我知道它是如何工作的,但为什么允许这个代码呢?
Ste*_*sop 14
访问控制在编译时执行,而不是在运行时执行.通常无法调用f()知道指向的对象的运行时类型ptr,因此不会检查派生类的访问说明符.这就是允许通话的原因.
至于为什么B级被允许使用私有功能覆盖 - 我不确定.当然B违反了它从A继承所暗示的接口,但一般来说C++语言并不总是强制继承接口,所以它的Just Plain Wrong并不意味着C++会阻止你.
所以我猜这个类B可能有一些用例 - 替换仍然适用于动态多态,但静态B不能替代A(例如,可以有调用的模板f,可以使用A作为参数但不能以B为参数).可能存在这种情况,这正是您想要的.当然,这可能只是其他一些考虑因素的意外后果.