仮想関数へのアクセスは、宣言時に指定されます。
後で仮想関数をオーバーライドする関数のアクセス規則が、
仮想関数のアクセス規則に影響を与えることはありません。
一般に、
オーバーライドするメンバー関数のアクセスは未知です。
クラス・オブジェクトを指すポインターまたは参照で仮想関数を呼び出す場合は、 仮想関数のアクセスの判別に、クラス・オブジェクトの型は使用されません。 代わりに、使用されるのは、クラス・オブジェクトを指すポインターまたは参照の型です。
次の例では、型 B* を持つポインターを使用して関数 f() を呼び出すと、 関数 f() へのアクセスの判別に bptr が使用されます。 クラス D で定義された f() の定義が実行されますが、 クラス B の中のメンバー関数 f() のアクセスが、使用されます。 型 D* を持つポインターを使用して関数 f() を呼び出すと、 関数 f() へのアクセスの判別に dptr が使用されます。 f() はクラス D で private と宣言されているので、 この呼び出しはエラーになります。
class B { public: virtual void f(); }; class D : public B { private: void f(); }; int main() { D dobj; B* bptr = &dobj; D* dptr = &dobj; // valid, virtual B::f() is public, // D::f() is called bptr->f(); // error, D::f() is private dptr->f(); }