38

重複の可能性:
C++ で「friend」を使用する必要があるのはいつですか?

私は自分の C++ (私は Java 開発者です) をブラッシュアップしてfriend classいて、しばらく忘れていたキーワードに出くわしました。これはキッチン シンクの一部にすぎない機能の 1 つですか、それとも単なるバニラ ゲッターではなく、これを行う正当な理由があるのでしょうか? 誰がデータにアクセスできるかを制限するという違いは理解していますが、これが必要になるシナリオが思い浮かびません。

注: 同様の質問を見たことがありますが、具体的には、これは単なる高度な機能であり、コードを見ている人が何をしているのかを理解するまで混乱させること以外に真の価値はありませんか?

4

11 に答える 11

41

賢明に使用すれば、friend キーワードがカプセル化を改善できるというコメントに同意します。フレンド クラスの最も一般的な (正当な!) 用途はテストである可能性があることを付け加えておきます。テスター クラスに、他のクライアント クラスよりも高いアクセス権を持たせたい場合があります。テスター クラスには、意図的に他のクラスから隠されている内部の詳細を確認する十分な理由がある場合があります。

于 2009-02-06T19:45:15.893 に答える
19

私の経験では、カプセル化を破るために使用される頻度と比較して、実際にデータのカプセル化を強化するフレンド (またはミュータブル、少し似ています) のケースはまれです。

私にとってはめったに役に立ちませんが、使用する場合は、以前は単一のクラスだったクラスを、共通のデータ/機能にアクセスする必要がある2つの別個のクラスに分割する必要があった場合です。

Outlaw Programmer のコメントに対応するために編集します。これには完全に同意します。それらを分割した後にクラスを友達にする以外のもう 1 つのオプションは、パブリック アクセサーを作成することです。これにより、カプセル化が壊れることがあります。一部の人々は、フレンドリー クラスが不適切に使用されているのを見て、カプセル化が何らかの形で壊れていると考えていると思います。多くの人は、それが正しく使用されているコードを見たことがないでしょう。それはまれなことだからです。私はあなたの言い方が好きですが、親しみやすさは、クラスを分割することを許可しないことと、すべてを一般に公開することの間の良い中間点です.

David Thornley に返信する編集: C++ がこのようなことを可能にする柔軟性は、C++ に入った設計上の決定の結果であることに同意します。それが、柔軟な言語で一般的に良いスタイルと悪いスタイルを理解することがさらに重要になる理由だと思います。Java の観点では、フレンド クラスを提供しないようにするべきではありませんが、C++ プログラマーとして、これらの非常に柔軟でありながら誤用されることもある言語構造の適切な使用法を定義することは、コミュニティとしての私たちの責任です。

Tom に対応するように編集: Mutable は必ずしもカプセル化を破るわけではありませんが、実際の状況で見た mutable キーワードの使用の多くはカプセル化を破ります。そもそもミュータブルの適切な使用法を実際に見つけて理解する必要があります。

于 2009-02-06T19:20:27.380 に答える
13

あるクラス (Factory) が別のクラス (Type) のインスタンスの作成を担当するようにしたい場合。Type のコンストラクターをプライベートにすることで、Factory のみが Type オブジェクトを作成できるようにすることができます。バリデータとして機能する他のクラスにチェックを委譲したい場合に便利です。使用シナリオは 1 つだけです。

PS 本当に C# に "friend" キーワードがありません...

于 2009-02-06T20:27:54.090 に答える
9

具体的なインスタンスは、あるクラスを別のファクトリ クラスを介してのみ作成するクラス ファクトリになります。そのため、コンストラクタをプライベートにし、ファクトリ クラスを生成されたクラスのフレンドにします。

2 インチ 12 ポイントの 3/4 インチ ドライブ ソケットのようなものです - あまり一般的ではありませんが、必要なときは、それを持っていることを非常に嬉しく思います。

于 2009-02-06T20:24:18.577 に答える
4

Memento デザインパターンに役立ちます

于 2009-02-06T19:24:57.697 に答える
2

フレンドに関する FAQ のセクション:こちら

フレンドに関する FQA のセクション:こちら

友人についての 2 つの異なる視点。

于 2009-02-06T20:26:57.353 に答える
1

フレンドシップは、複数のクラスや関数が連携して同じ抽象化またはインターフェイスを提供する場合に使用されます。古典的な例は、ある種の数値クラスを実装しており、すべての非メンバー演算子関数 (*、-、+、<< など) にフレンドシップが与えられているため、数値クラスのプライベート データを操作できます。

このような使用例はややまれですが、実際に存在し、friend は非常に便利です。

于 2009-02-06T20:15:39.780 に答える
1

このfriend構文は、めったに使用されない言語の機能の 1 つだと考えていますが、それが役に立たないわけではありません。クラスを作成する必要があるパターンはいくつかありますがfriend、その多くは既にこのサイトの右側の「関連」バーにあります。====>

于 2009-02-06T19:23:22.303 に答える
1

これは、カプセル化の理由を無視することなく、フレンド クラスを合法的に使用できるいくつかの例の 1 つです。

MyClass は GeneralClass を継承しています。MyClass が大きくなったので、MyClass の機能の一部をカプセル化するために HelperClass を作成しました。ただし、HelperClass は、その機能を適切に実行するために GeneralClass の保護された関数にアクセスする必要があるため、HelperClass を MyClass のフレンドにします。

これは、誰もが利用できる必要がないため、保護された関数を公開するよりも優れていますが、MyClass が複雑になりすぎないように、コードを OOP の方法で編成しておくのに役立ちます。HelperClass は継承によって MyClass に具体的に関連付けられていませんが、何らかの論理的な接続があり、コードと設計で「フレンド」として具体化されているため、これは理にかなっています。

于 2010-12-15T18:15:58.090 に答える
0

私は常に (そして唯一) フレンドを使用して、プライベート メソッドの単体テストを行います。これを行う唯一の方法は、パブリック インターフェイスに大量のテスト メソッドをロードすることです。

このようなもの:

class cMyClassTest;

class cMyClass
{
public:
.....

private:
friend cMyClassTest;
int calc();     // tricky algorithm, test carefully

};

class cMyClassTest
{
public:
int test_calc()
{
    cMyClass test;
    ....
    int result = test.calc();

    if( result == 42 )
        return 1;
    return 0;
}
};
于 2009-02-12T16:18:50.187 に答える
0

フレンドクラスは、他のクラスから変数の値にアクセスすることを私たち全員が知っていることを意味するため、主に値を使用するために使用されるため、他のクラスの値をメイン関数に返し、次に必要なクラスメンバー関数にメインを返す必要はありませんが、クラスである問題が他のクラスのフレンドである場合、フレンド クラスはそのクラスの下にある必要があります

于 2010-01-27T13:33:37.010 に答える