コピー代入演算子には、通常の署名があります。
my_class & operator = (my_class const & rhs);
次の署名には実用的な用途がありますか?
my_class const & operator = (my_class const & rhs);
どちらか一方のみを定義できますが、両方を定義することはできません。
コピー代入演算子には、通常の署名があります。
my_class & operator = (my_class const & rhs);
次の署名には実用的な用途がありますか?
my_class const & operator = (my_class const & rhs);
どちらか一方のみを定義できますが、両方を定義することはできません。
copy-assignment の戻り値の型を非 const 参照にする主な理由は、それが標準の「割り当て可能」の要件であるためです。
戻り値の型をconst
参照にすると、クラスは標準ライブラリ コンテナーで使用するための要件を満たせなくなります。
そうしないでください。クライアントが次のようなものを書くのを防ぎます。
(a = b).non_const_method();
長い形式の代わりに:
a = b;
a.non_const_method();
省略形が気に入らないかもしれませんが、コードをどのように記述したいかを決定するのは、ライブラリのユーザー次第です。
C ++での代入演算子のオーバーロードからの1つを反映した答え:
aを返すと、const&
割り当ての連鎖が可能になります。
a = b = c;
しかし、より珍しい使用法のいくつかを許可しません:
(a = b) = c;
これにより、代入演算子のセマンティクスはCの場合と同様になり、=
演算子によって返される値は左辺値ではないことに注意してください。C ++では、標準で変更されたため、=
演算子は左のオペランドの型を返すため、結果は左辺値になります。しかし、Steve Jessopが別の回答へのコメントで述べたように、それはコンパイラが受け入れるようにします
(a = b) = c;
a
ビルトインの場合でも、シーケンスポイントが介在せずに2回変更されるため、ビルトインの動作は未定義になります。関数呼び出しがシーケンスポイントとして機能するoperator=()
ため、ビルトイン以外の場合、この問題は回避されます。operator=()
const&
左辺値のセマンティクスを明確に許可する(そして、それらのセマンティクスで適切に動作するようにクラスを設計する)場合を除いて、を返すことに問題はありません。あなたがユーザーがの結果で何か変わったことをしたいのならoperator=()
、私はクラスがデザインではなく偶然にそれを正しくすることを望むよりもそれを許可しないことを望みます。
また。あなたが言っている間注意してください:
どちらか一方のみを定義できますが、両方を定義することはできません。
これは、C++の関数シグネチャが戻り値の型を考慮していないためです。operator=()
ただし、異なるパラメーターを受け取り、パラメーターのタイプに適した異なるタイプを返す複数の割り当てオペレーターを使用することもできます。
my_class& operator=( my_class& rhs);
my_class const& operator=(my_class const& rhs);
しかし、これがあなたに何を買うのか完全にはわかりません。割り当てられているオブジェクト(おそらく返される参照)はどちらの場合も非定数であるconst&
ため、の右側がであるという理由だけで=
を返す論理的な理由はありませんconst
。しかし、多分私は何かが欠けています...
効果的な C++ は、これにより C++ の組み込み型との互換性が失われると説明しています。
プレーンなint
s でこれを行うことができます:
(x = y) = z;
だから彼は、これがどんなにばかげているように見えても、自分のタイプでも同じことができるはずだと考えています.
この例は第 2 版にはありますが、第 3 版にはありません。ただし、この第 3 版からの引用、項目 10 は同じことを伝えています。
[...] 代入は左側の引数への参照を返します。これは、クラスに代入演算子を実装するときに従うべき規則です。
class Widget {
public:
...
Widget& operator=(const Widget& rhs) // return type is a reference to
{ // the current class
...
return *this; // return the left-hand object
}
...
};
なぜ誰もが夢中になっているの(a = b) = c
ですか?それは偶然に書かれたことがありますか?
変更された代入の結果の予期しない有用性がおそらくあります。おかしく見えるでっち上げの例に対して恣意的なルールを作るだけではありません。意味的には である必要はないので、レキシカルな副作用のためにconst
宣言しないでください。const
const &
以下は、代入のために中断するやや合理的なコードの例です。
my_class &ref = a = b;
const の他の使用法と同様に、本当にユーザーに変更を許可したい場合を除き、const がデフォルトです。
はい、そうあるべきですconst
。それ以外の場合、クライアントはこれを行うことができます:
class MyClass
{
public:
MyClass & operator = (MyClass const & rhs);
}
void Foo() {
MyClass a, b, c;
(a = b) = c; //Yikes!
}