他のクラスのメンバー関数を、friend関数にできる。
struct Y { void f() ; } ; struct X { friend void Y::f() ; // OK } ;
このように、他のクラスのメンバー関数をfriend宣言することで、クラスすべてのメンバーではなく、あるメンバーだけを、friendとすることができる。
オーバーライドしたvirtual関数のアクセス指定は、オーバーライドされるvirtual関数には影響を及ぼさない。
class Base { public : virtual void f() { } // publicメンバー } ; class Derived : public Base { private : void f() { } // Base::fをオーバーライド、privateメンバー } ; int main() { Derived d ; d.f() ; // エラー、Derived::fはprivateメンバー Base & ref = d ; ref.f() ; // OK、Derived::fを呼び出す }
Base経由で、privateメンバーであるDerived::fを呼び出すことができる。これは、virtual関数のアクセスチェックは、呼び出す時点での宣言により、静的に決定されるためだ。関数mainから、Base::fにはアクセスできるため、ref.f()という式はエラーにならない。後は、通常通り、virtual関数呼び出しによって、オブジェクトの型である、Derivedのfが、正しく呼び出される。
もちろん、いま執筆中の参考書には、これらの仕様も漏れ無く説明されている。
似たような話で、gccやclangでこれが出来るのは何ででしょうね。なんかBCCだと公開水準を制限できないとか言って別のErrorになったような気がしますが。
ReplyDeletestruct Base
{
static void Example();
};
class Derived:public Base
{
Base::Example;
};
Derived::Example();// Error
BCCのような古代のコンパイラーを使ってはいけません。
ReplyDeleteその文法はAccess declarationといって、C++03ですらdeprecatedな文法です。使ってはいけません。
かわりにusing declarationを使いましょう。