9

http://www.learncpp.com/cpp-tutorial/142-function-template-instances/から

class Cents
{
private:
    int m_nCents;
public:
    Cents(int nCents)
        : m_nCents(nCents)
    {
    }

    friend bool operator>(Cents &c1, Cents&c2)  // <--- why friend?
    {
        return (c1.m_nCents > c2.m_nCents) ? true: false;
    }
};

次のように実装することもできます。

class Cents
{
private:
    int m_nCents;
public:
    Cents(int nCents)
        : m_nCents(nCents)
    {
    }

    bool operator> (Cents& c2)  // <---
    {
        return (this->m_nCents > c2.m_nCents) ? true: false;
    }
};

2番目の実装を使用することの欠点はありますか?

4

4 に答える 4

14

パラメータとしてconst参照を使用していると仮定すると、最初の実装は次のような条件で使用できます。bool b = 42 > c;これにより、2番目の実装でコンパイラエラーが発生します。Centこれにより、整数を使用してオブジェクトが自動的に作成42され(コンストラクターはとして定義されていないためexplicit)、friend関数を使用して比較します。このFAQのポイント7を参照してください

于 2012-02-28T05:49:48.727 に答える
0

1つ目はクラスメンバーオーバーロード演算子として定義され、2つ目は非メンバーオーバーロード演算子です。非メンバー関数がプライベートメンバー private: int m_nCents;に アクセスする場合は、friend追加する必要があります。に変更しpublic:int m_nCents;ても機能しません。friendメンバーのアクセス制限のためではなく、ルールのようです。ただし、非メンバー演算子をクラス本体の外に移動して、パブリックメンバー変数にアクセスすることはできます。もっと良いアイデアはありますか?私は混乱しています。ALL非メンバー演算子(オペランドと同じパラメーター番号を持ち、メンバー関数として呼び出すことはできません)はfriend、クラス本体のように宣言する必要があると思います。

>は、オペランドごとに2つのパラメーターを持つ二項演算子です。クラスメンバーのオーバーロード演算子には、 1つの明示的なパラメーターと暗黙的なパラメーター>しかないことがわかりました。非会員のオペレーターは2つ持っている必要があります。this

class Cents{
  private:
     int m_nCents;
  public:
  Cents(int nCents)
     : m_nCents(nCents)
   {
   }

   friend bool operator>(Cents &c1, Cents&c2); //Nomember 

   bool operator<(Cents &c1); //class member
};

bool operator>(Cents &c1, Cents&c2)  // <--- why friend?
{
   //cout << "in >"  << endl;
   return (c1.m_nCents > c2.m_nCents) ? true: false;
}

bool Cents::operator<(Cents &c1)
{
    //cout << "in <"  << endl;
    return (this->m_nCents < c1.m_nCents) ? true: false;
}

int main(){
 //nomember
 //if(poor.operator>(rich))  //compiler error 
 if(poor > rich){
     cout << "oh yeal!" << endl;
 }
 else
 {
     cout << "oh no!" << endl;
 }

 //member
 //if(poor.operator<(rich)) //can call this way
 if(poor.operator<(rich)){
     cout << "oh yeal!" << endl;
 }
 else
 {
     cout << "oh no!" << endl;
 }

}

実装をクラス本体から移動します。Cents::これで、クラスメンバー演算子がメンバー関数と同じように修飾子を持っていることがわかります。

于 2012-02-28T06:15:37.603 に答える
-1

一般的な実際の例のほとんどに大きな違いは見られません。

私は2番目のオプションを好みます。これは直接関連付けられclassます。さらに、次の構文がより適切です。

bool operator> (const Cents& c2) const
{         //    ^^^^^            ^^^^^
  return (this->m_nCents > c2.m_nCents); // simple
}
于 2012-02-28T05:51:24.953 に答える
-2

パブリックメソッドに友達のタグを付ける理由はありません。フレンド関数は、プライベートメンバーまたは保護されたメンバーにアクセスする無関係のクラスに役立ちます。

そうは言っても、最初の実装から友達を削除するだけで、問題なく動作します。

于 2012-02-28T05:55:09.407 に答える