次のコードを実行してみました。関数 "g" は、X では公開されているが Y では非公開である関数 "f" を呼び出していることに注意してください。
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;
継承を protected から public に変更すると、コードが機能し、次の出力が得られます。
From Y
継承がパブリックの場合、関数 "f" の呼び出しにプライベート アクセス制限が適用されていないように思えます (Y::f が X から呼び出されたため)。このコードを実行する前に、アクセス制限のために常にコンパイル時エラーが発生するはずだと考えていました (これは誤りであることが証明されました)。
どういうわけか、継承を public から protected に変更すると、これが修正され、Y::f への呼び出しが有効になりません。誰でも理由を説明できますか?