operator=が正しく定義されている場合、コピーコンストラクタとして以下を使用しても大丈夫ですか?
MyClass::MyClass(MyClass const &_copy)
{
*this = _copy;
}
operator=が正しく定義されている場合、コピーコンストラクタとして以下を使用しても大丈夫ですか?
MyClass::MyClass(MyClass const &_copy)
{
*this = _copy;
}
のすべてのメンバーがMyClass既定のコンストラクターを持っている場合は、はい。
通常は逆であることに注意してください。
class MyClass
{
public:
MyClass(MyClass const&); // Implemented
void swap(MyClass&) throw(); // Implemented
MyClass& operator=(MyClass rhs) { rhs.swap(*this); return *this; }
};
operator=コピー コンストラクターが呼び出されるように値渡しします。swapはスローしないことが保証されているため、すべてが例外セーフであることに注意してください (実装でこれを確認する必要があります)。
要求に応じて、値による呼び出しについて編集します。次のoperator=ように記述できます。
MyClass& MyClass::operator=(MyClass const& rhs)
{
MyClass tmp(rhs);
tmp.swap(*this);
return *this;
}
C++ の学生は通常、クラス インスタンスを参照渡しするように指示されます。これは、クラス インスタンスが値渡しされるとコピー コンストラクターが呼び出されるためです。この場合、rhsとにかくコピーする必要があるため、値渡しは問題ありません。
したがって、operator=(最初のバージョン、値による呼び出し)は次のようになります。
rhs(コピー コンストラクターを介して、自動的に呼び出されます)*this *thisおよび let rhs(古い値を含む) は、メソッドの終了時に破棄されます。さて、この値による呼び出しには追加のボーナスがあります。渡されるオブジェクトoperator=(または引数を値で取得する任意の関数) が一時オブジェクトである場合、コンパイラはコピーをまったく作成できません (通常は作成します)。これはコピー省略と呼ばれます。
したがって、rhsが一時的な場合、コピーは作成されません。残っているのは次のとおりです。
thisとrhsコンテンツrhsしたがって、この場合、値渡しは参照渡しよりも効率的です。
例外セーフ コピー コンストラクターに関して operator= を実装することをお勧めします。この手法の説明と、それが良いアイデアである理由については、Herb Sutter の例 4. を参照してください。
この実装は、割り当てを行う前に最初に呼び出されるため、すべてのデータ メンバー (および基本クラス) の既定のコンストラクターが MyClass から使用可能であり、アクセスできることを意味します。この場合でも、コンストラクターに対してこの余分な呼び出しを行うと、コストが高くなる可能性があります (クラスの内容によって異なります)。
たとえそれがより多くのコードを書くことを意味するとしても、初期化リストを介してコピーコンストラクターの個別の実装に固執します。
別のこと: この実装には副作用がある可能性があります (たとえば、メンバーを動的に割り当てた場合)。
最終結果は同じですが、メンバーは最初にデフォルトで初期化され、その後のみコピーされます。
'高価な'メンバーを使用すると、初期化子リストを使用してコピーを作成する方が適切です。
struct C {
ExpensiveType member;
C( const C& other ): member(other.member) {}
};
};
はい。
個人的には、equal演算子をオーバーロードしたり、コピーコンストラクターを記述したりしてコンパイラーに任せたりしないのに、クラスにポインターがない場合。シャローコピーが実装され、すべてのメンバーデータがコピーされていることが確実にわかりますが、=opをオーバーロードすると; 次に、データメンバーを追加してから、問題が発生するオーバーロードの更新を忘れます。
作業代入演算子 (コピー演算子) があれば、技術的には問題ありません。
ただし、次の理由により、コピー アンド スワップを優先する必要があります。
MyClassがメモリを割り当てているか、変更可能である 場合、これは問題ないと思います。
@Alexandre - 代入演算子での値渡しについてはわかりません。そこでコピーコンストラクターを呼び出すことで得られる利点は何ですか? これは代入演算子を固定するつもりですか?
PS コメントの書き方がわかりません。それとも、コメントを書くことを許可されていないのかもしれません。