我试过运行以下代码。请注意,函数“g”调用函数“f”,该函数在 X 中是公共的,但在 Y 中是私有的。
class X{
public:
virtual void f(void){cout<<"From X\n";}
virtual void g(X* x) { x->f();}
};
class Y: protected X{
private:
void f(void){cout<<"From Y\n";}
};
int main() {
Y y = Y();
Y *py = &y;
X* px = py;
py->g(py);
return 0;
}
输出是(注意继承受到保护):
prog.cpp: In function ‘int main()’:
prog.cpp:18:10: error: ‘X’ is an inaccessible base of ‘Y’
X* px = py;
^
prog.cpp:7:16: error: ‘virtual void X::g(X*)’ is inaccessible
virtual void g(X* x) { x->f();}
^
prog.cpp:19:10: error: within this context
py->g(py);
^
prog.cpp:19:10: error: ‘X’ is not an accessible base of ‘Y’
prog.cpp:19:10: error: ‘X’ is an inaccessible base of ‘Y’
prog.cpp:18:5: warning: unused variable ‘px’ [-Wunused-variable]
X* px = py;
如果我将继承从受保护更改为公共,则代码有效,我得到以下输出:
From Y
在我看来,当继承是公共的(因为 Y::f 是从 X 调用的)时,对函数“f”的调用没有强制执行私有访问限制。在运行这段代码之前,我认为由于访问限制(这被证明是错误的),我应该总是得到一个编译时错误。
不知何故,将继承从 public 更改为 protected 解决了这个问题,并且不会启用对 Y::f 的调用。谁能解释为什么?