26

私は二重リンクリストを作成している途中で、operator =をオーバーロードして、リストを別のリストと等しくしました。

template<class T>
void operator=(const list<T>& lst)
{
    clear();
    copy(lst);
    return;
}

しかし、コンパイルしようとすると、このエラーが発生します。

container_def.h(74) : error C2801: 'operator =' must be a non-static member

また、役立つ場合は、74行目が定義の最後の行であり、「}」が付いています。

4

4 に答える 4

24

正確に言うと、演算子のオーバーロードはメンバー関数でなければなりません。(クラス内で宣言)

template<class T>
void list<T>::operator=(const list<T>& rhs)
{
    ...
}

また、LHSを=から返すことをお勧めします。そうすれば、(のようにa = b = c) チェーンできるようになります。list<T>& list<T>::operator=....

于 2009-05-15T23:40:34.233 に答える
20

その演算子をクラス定義内に入れます。operator=それは特別であり、とにかく非会員としてそれを書いても何かを得ることはないので、それは会員でなければなりません. 非会員オペレーターには、2 つの重要な主な利点があります。

  • 演算子呼び出しの右側と左側の暗黙的な変換
  • クラスの内部について知る必要はありません。機能は非会員非友人として実現できます。

の場合operator=、どちらも使えません。変換の一時的な結果に割り当てることは意味がなくoperator=、ほとんどの場合、内部にアクセスする必要があります。さらに、特別なoperator=ものを指定しない場合は、C++ によって自動的に特別なものが提供されます (いわゆるコピー代入演算子)。operator=非メンバーとしてオーバーロードできるようにすると、明らかに実用的な利益が得られないため、追加の複雑さが導入されるため、許可されていません。

したがって、コードを次のように変更します (これは、がコピー代入演算子でoperator=なくlist<T>、aから別のものに代入することを前提としています。これはあなたの質問からは明らかではありません):

class MyClass {
...
    template<class T>
    MyClass& operator=(const list<T>& lst)
    {
        clear();
        copy(lst);
        return *this;
    }
...
};

operator=aが再び自身への参照を返すのはかなり標準的です。その慣習に従うことをお勧めします。voidプログラマーには見慣れたもので、突然戻ってきたら驚くかもしれません。

于 2009-05-15T23:44:32.663 に答える
6

演算子をメンバー関数としてオーバーロードする場合は、次のテンプレートを使用する必要があります。

class A {
  A& operator=(const A& other) {
    if (this != &other) {
      ...
    }
    return *this;
  }
}

注意すべき3つのこと:

  1. (上記のように)代入演算子を使用して自己代入を確認します。
  2. 引数はconst参照である必要があります。と
  3. 操作の結果を非定数参照として返します。ここで*thisを返すと、演算子の連鎖が可能になります。

クラスの外部の演算子をオーバーロードすることもできます。これは、代入演算子では実行できないため、この例には関係ありませんが、多くの場合、メンバー関数よりも優れているため、注目に値します。典型的な形式は次のとおりです。

class A {
  friend const A& operator+(const A& a, const A& b);
  ...
}
const A& operator+(const A& a, const A& b) {
  A& ret = ...
  return ret;
}

これはconst参照を返すため、これを行うことはできません。

(a + b) = c
于 2009-05-15T23:40:34.577 に答える
-1

C++ 標準から、「二項演算子」:

「二項演算子は、1 つのパラメーターを持つ非静的メンバー関数によって、または 2 つのパラメーターを持つ非メンバー関数によって実装される必要があります」

これをクラスでメンバーとして定義するか、静的メソッドにする必要があります (この場合、2 つのパラメーター (lval と rval の両方) を取る必要があります)。

于 2009-05-15T23:47:40.597 に答える