1

friend私は、自分のクラス以外のプライベートメンバーにアクセスするために、という単語を使用することを考えています。たとえば、クラスAがあり、AIのメソッド内のクラスBの属性のプライベートメソッドにアクセスする必要がある場合、そのメソッドをフレンドとして宣言できます。

ただし、次のコードを参照してください。

#include <cstdlib>

class Coord {
  private:
    int x, y;
  public:
    Coord (int i1, int i2) : x(i1), y(i2) {
    }
    friend Coord operator- (Coord const& c1, Coord const& c2) {
        return Coord(c1.x-c2.x, c1.y-c2.y);
    }
    Coord abs() {
        return Coord(std::abs(x),std::abs(y));
    }
};

友人として、オペレーターに過負荷をかける可能性のあるメリットはどれですか?なぜ誰かが興味を持っているのか、私にはよくわかりません。

私はそれについてたくさん読みましたが、明確な考えがわかりませんでした。

誰かが私が事実を観察できる小さな例を書くことができますか?

4

2 に答える 2

3

Herb Suttersと Scott Meyersの例を見てみましょう。

ここに要約:

最初に: 演算子を - 非メンバーのようにします: c = a - b を実行すると、マイナスはどのオブジェクトに属しますか? ?b? またはなし。ほとんどの人はどれにも同意しないため、非メンバーです。2 つ目: オペレーターはプライベート コンテンツを変更する必要があるため、フレンドを作成するか、ゲッターなどのアクセス関数を使用します。そのため、ほとんどの人は友達に固執します。

あなたの特定の例では、フレンド宣言の直後に、グローバルフレンド関数を定義する最もコンパクトな方法である定義が続きます。

于 2012-12-08T15:36:32.670 に答える
2

演算子関数がメンバー関数として実装されている場合、左端 (または唯一) のオペランドは演算子のクラスのオブジェクト (またはオブジェクトへの参照) でなければなりません。左オペランドが異なるクラスまたは基本型のオブジェクトでなければならない場合、この演算子関数は非メンバー関数として実装する必要があります (たとえば、オーバーロードの場合、それぞれストリーム挿入<<および>>ストリーム抽出演算子として)。

非メンバー演算子関数は、その関数がそのクラスのメンバーに直接friendアクセスする必要がある場合、そのクラスの にするprivateことができます。protected特定のクラスの演算子メンバー関数は、二項演算子の左オペランドが明確にそのクラスのオブジェクトである場合、または単項演算子の単一オペランドがそのクラスのオブジェクトである場合にのみ (コンパイラによって暗黙的に) 呼び出されます。

非メンバー関数を選択して演算子をオーバーロードするもう 1 つの理由は、演算子を交換可能にするためです。

たとえば、 type の基本型変数number、クラス(基になるハードウェアのマシン ワード サイズによって整数が制限されるのではなく、整数が任意に大きくなる可能性があるクラス)long intのオブジェクトがあるとします。減算演算子 ( ) は、aと aの差(式)、または aと aの差(式 ) として一時オブジェクトを生成します。したがって、減算演算子は交換可能である必要があります (2 つの基本型オペランドの場合とまったく同じです)。問題は、クラス オブジェクトが左側に表示されなければならないことです。bigInteger1HugeInteger-HugeIntegerHugeIntegerlong intbigInteger1 - numberlong intHugeIntegernumber - bigInteger1その演算子がメンバー関数としてオーバーロードされる場合は、減算演算子の。そのため、演算子を非メンバー関数としてオーバーロードしてHugeInteger、減算の右側に表示できるようにします。左側の を処理する関数は、引き続きメンバー関数にすることができますoperator-HugeInteger非メンバー関数は、単純にその引数を交換してメンバー関数を呼び出すことができます。

于 2012-12-08T15:37:05.453 に答える