はじめに
Effective C++ 第3版のイントロダクションxxiiのページから勉強していきます。
今回扱うのは、「コピーコンストラクタとコピー代入演算子」 についてです。
Effective C++ 第3版 - イントロダクションxxii -
コピーコンストラクタとコピー代入演算子
コピーコンストラクタとは?
オブジェクトを「同じ型の別のオブジェクト」で初期化するときに使われる。
コピー代入演算子とは?
オブジェクトを「同じ型の別のオブジェクト」で代入するときに使われる。
下にコピーコンストラクタを用いてオブジェクトを初期化した場合とコピー代入演算子を用いてオブジェクトの代入を行った場合のサンプルコードを示します。
下のサンプルコードでコンストラクタでオブジェクトを初期化している箇所は、、
Widget a(1);
の部分です。
コピーコンストラクタでオブジェクトを初期化している箇所は、
Widget b(a);
Widget c = b;
の部分です。
コピー代入演算子でオブジェクトの代入をしている箇所は、
a = b;
の部分です。
新しいオブジェクトが定義されている時には必ず、コンストラクタ or コピーコンストラクタが呼ばれていることが分かる。
そのため、代入しているのは, a = bの1回だけであることが分かる。
ちなみに、各変数a, b, cのアドレスは、
のようになっていることが分かる。
そのため、値だけが代入されており、例え、b を代入した a をいじっても bには関係ないことが分かる。
ポインタの代入とは異なる。
分からなかった点
コピーコンストラクタに explicitを付けるべきかどうか?
本のサンプルコードには乗ってなかったが、前のページで理由がなければコンストラクタには explicit を付けろと書いてあった。。。
サンプルコード
# include <iostream>
class Widget {
public:
explicit Widget(int a) { std::cout << "コンストラクタ" << std::endl; };
Widget(const Widget& rhs) { std::cout << "コピーコンストラクタ" << std::endl; };
Widget& operator=(const Widget& rhs) { std::cout << "コピー代入演算子" << std::endl; };
~Widget(){};
};
int main(int argc, char* argv[]) {
std::cout << "intro_default_constructor3.cpp" << std::endl;
Widget a(1); // コンストラクタ
Widget b(a); // コピーコンストラクタ
a = b; // コピー代入演算子
Widget c = b; // コピーコンストラクタ
std::cout << "aのアドレス : " << &a << std::endl;
std::cout << "bのアドレス : " << &b << std::endl;
std::cout << "cのアドレス : " << &c << std::endl;
}
実行結果
参考文献
・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0