「演算子 = 非静的メンバーである必要がある」とはどういう意味ですか?
-
22-08-2019 - |
質問
私は二重リンクリストを作成中ですが、リストを別のリストと等しくするために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 行目は「}」を含む定義の最後の行です。
解決
まさにそれは言う:演算子のオーバーロードは、メンバ関数でなければなりません。 (クラス内で宣言)
template<class T>
void list<T>::operator=(const list<T>& rhs)
{
...
}
また、それはからLHSを返すために、おそらく良いアイデアだ=あなたは(a = b = c
のように)それをチェーンすることができます - ので、それを作ります
list<T>& list<T>::operator=....
他のヒント
その演算子をクラス定義内に置きます。メンバーである必要があるため、 operator=
は特別であり、非メンバーとして書いても何も得られません。非会員オペレーターには、次の 2 つの重要な利点があります。
- 権利の暗黙的な変換 そして 演算子呼び出しの左側
- クラスの内部について知る必要はありません。非会員・非フレンドとして機能を実現できます。
のために operator=
, 、どちらも使えません。変換の一時的な結果に代入することは意味がありません。 operator=
ほとんどの場合、内部へのアクセスが必要になります。さらに、特別な operator=
これ (いわゆるコピー代入演算子) を指定しない場合、C++ によって自動的に提供されます。過負荷を可能にする operator=
非メンバーが追加の複雑さを導入することは、明らかに実質的な利益がないため、許可されません。
したがって、次のようにコードを変更します (これは、 operator=
は ない コピー代入演算子ですが、 list<T>
何か他のものに。これはあなたの質問からは明らかではありません):
class MyClass {
...
template<class T>
MyClass& operator=(const list<T>& lst)
{
clear();
copy(lst);
return *this;
}
...
};
それはかなり標準的なことです operator=
自身への参照を再度返します。その習慣に従うことをお勧めします。プログラマにとっては見慣れたものであり、もし戻ってきたら驚くかもしれません void
突然。
演算子をメンバー関数としてオーバーロードする場合は、このテンプレートを使用する必要があります。
class A {
A& operator=(const A& other) {
if (this != &other) {
...
}
return *this;
}
}
注意すべき 3 つの点:
- (上記と同様) 代入演算子を使用して自己代入を確認します。
- 引数は const 参照である必要があります。そして
- 演算の結果を非 const 参照として返します。*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
C ++標準から、 "バイナリ演算子":
「のバイナリ演算子は、2つのパラメータを用いて一つのパラメータと非静的メンバ関数によって、または非メンバ関数のいずれかによって実施されなければなりません」
それはあなたがメンバーとして、クラスでこれを定義する、またはそれにはLVALとrvalに両方のために(2つのパラメータを取る必要があり、その場合には、静的メソッド()を作成したいと考えています。