2009-02-21 2 views

答えて

3

friendクラスを使用するのと同じ理由でfriendクラスを使用しますが、(クラス全体ではなく)メンバ関数を使用します。いくつかの良い説明はthis threadです。

フレンド機能とクラスはカプセル化に違反しますが、いくつかのシナリオでは役立ちます。たとえば、テストハーネスがクラス内部にアクセスして、ホワイトボックステストを実行できるようにすることができます。クラス全体をテストハーネスに開放するのではなく、テストハーネスが必要とする内部にアクセスする特定の関数を開くことができます。これはまだカプセル化に違反していますが、クラス全体を開くよりもリスクは低くなります。

フレンドのクラスと機能についての詳細は、this articleを参照してください。

0

実際の状況では、公共/民間/保護された保護レベルでは不十分な場合があります。したがって、メソッドを公にアクセスできるようにすることなく、小さなget-out節を提供します。

これは、Javaが「パッケージ」保護レベルを使用するのと同じ方法で個人的に使用します。
アクセスが必要な同じパッケージにクラスがある場合は、友人の使用を検討します。それが別のパッケージのクラスであれば、私はアクセスが必要なこの他のクラスが私のデザインを見ている理由を知りません。

1

C++ FAQ Lite:

は時々友人が構文的に優れている参照してください(例えば、メンバーが最初になるように、それを必要としながら、クラスフレッドに、フレンド関数は、フレッド・パラメータは二ことを可能にします)。 friend関数の別の良い使い方は、バイナリインミックス算術演​​算子です。たとえば、aComplex + aComplexは、aFloat + aComplexも許可したい場合はメンバーとしてではなく、友人として定義する必要があります(メンバー関数は左手引数の宣言を許可しません。メンバー関数呼び出しの受信者)。

2

物理的に複数のC++クラスまたは関数にまたがる必要がある抽象またはインターフェイスを作成しようとすると、Friend関数およびクラスはカプセル化に違反しません。それが友人が発明された理由です。

これらのタイプのケースは頻繁には発生しませんが、異なるクラスや機能を持つ抽象またはインターフェイスを強制的に実装することがあります。古典的な例では、いくつかのタイプの複素数クラスを実装しています。非メンバ演算子関数は、メインの複素数クラスに友好関係を与えられます。

また、C++でCORBAを使用してプログラミングするときにこれを思い出します。 CORBAは私に、CORBAサーバントを実装するための別のクラスを持たせなければなりませんでした。しかし、私たちのソフトウェアの特定の部分については、これらを1つのインターフェースとして結びつける必要がありました。友情によって、この2つのクラスが協力して、ソフトウェアの一部にシームレスなサービスを提供することができました。

他のクラスの特定のメンバー機能をクラスのメンバーとしてマークする機能を持つことは、見知らぬ人に見えるかもしれませんが、友だちをしっかりと制御する方法に過ぎません。あなたの友人として他のクラス全体を "in"にする代わりに、メンバー関数のうちの1つだけにアクセスすることを許可します。繰り返しますが、これは一般的ではありませんが、非常にが必要な場合に便利です。

+1

+1 "違反しないでください"。しかし、それは複雑で合理的な、最も数値的なクラスの場合には役に立たない... –

0

関連する1つの点:メンバークラスは、そのクラスを含むクラスのプライベートな部分にアクセスできます。これは時には "友人"のより良い代替手段であるかもしれません。ここで

class A 
{ 
private: 
    int b; 
public: 
    class MemberNotFriend { 
    public: 
    static void test() { 
     A a; 
     a.b = 0; 
    } 
    }; 


}; 


void test() 
{ 
    A::MemberNotFriend::test(); 
} 
0

は、私は友人の機能を使用していますかの簡単な、具体的な例である:

私は、各スプライトオブジェクトはプライベートメンバーとしてX、Y位置のようにその情報を格納し、ゲームを持っています。 しかし、私はゲームオブジェクトをレンダリングから分離したい:ゲームオブジェクトは、レンダリング方法の正確な詳細を必要としない。ゲームオブジェクトはゲーム状態のみを記憶し、このゲーム状態は多数の異なる方法でレンダリングされる。

したがって、ゲームオブジェクトクラスにはフレンド関数render()があります。 render()関数はゲームオブジェクトクラスの外で実装されますが、必要に応じてゲームオブジェクトをレンダリングするためにX、Yの位置の位置membefrsにアクセスできます。

関連する問題