7

C ++では、クラスへの非const参照を取得するコピーコンストラクターとoperator =を定義した場合でも、コンパイラーはconst参照のデフォルトバージョンを提供することになっていますか?

struct Test {
  Test(Test &rhs);
  Test &operator=(Test &rhs);

private:
  // Do I still need to declare these to avoid automatic definitions?
  Test(const Test &rhs);
  Test &operator=(const Test &rhs);
};
4

2 に答える 2

7

いいえ、コピーコンストラクターと代入演算子を定義する場合、コンパイラーはそれ自体を暗黙的に宣言または定義しません。copy-constructorの定義では、引数をconstまたはnon-const参照のいずれかで取得できるため、コンストラクターは実際にはcopy-constructorであることに注意してください。同様にoperator=

[詳細の大部分を省略します。特に、どのような状況で暗黙的に宣言された特殊メンバー関数も暗黙的に定義されます]

12.8 [class.copy] / 2クラスXの非テンプレートコンストラクターは、最初のパラメーターがタイプX&、const X&、volatile X&、またはconst volatile X&であり、他のパラメーターがないか、他のすべてのパラメーターがない場合、コピーコンストラクターです。パラメータにはデフォルトの引数(8.3.6)があります。

12.8 [class.copy] / 7クラス定義でコピーコンストラクターが明示的に宣言されていない場合は、暗黙的に宣言されます。

12.8 [class.copy]/17ユーザー宣言のコピー代入演算子X::operator =は、クラスXの非静的非テンプレートメンバー関数であり、タイプX、X&、const X&、volatile X&、またはconstのパラメーターが1つだけあります。揮発性X&。

12.8 [class.copy] / 18クラス定義がコピー代入演算子を明示的に宣言していない場合、暗黙的に宣言されます。

于 2012-08-13T14:50:41.640 に答える
1

いいえ、独自のコピーコンストラクターまたはコピー代入演算子を宣言すると(正規性を使用するかどうかに関係なくconst)、コンパイラーはそれを実行しなくなります。

しかし、非定数参照によってこれを行うことは、驚き最小の原則に違反する教科書の例です。誰もがconstオブジェクトをから割り当てることができ、右側が変更されないことを期待しています。前者はコンパイラがそれを捕らえるほど悪くはありませんが、後者はさまざまな見つけにくいバグを引き起こす可能性があります。

移動セマンティクスを実装しようとしていて、C ++ 11を使用できない場合は、特別な移動メソッドを作成し、「移動」構築をまったく許可しないことをお勧めします。C ++ 11を使用できる場合は、組み込みの右辺値参照を使用してください。

于 2012-08-13T14:59:07.100 に答える