はじめに
Effective C++ 第3版のイントロダクションxxiiのページから勉強していきます。
今回は、前回からの続きの、「コピーコンストラクタが呼ばれる場合」についです。
Effective C++ 第3版 - イントロダクションxxii -
コピーコンストラクタが呼ばれる場合
コピーコンストラクタが主に呼び出される場合とは?
前回の投稿では、「コピーコンストラクタは、オブジェクトを「同じ型の別のオブジェクト」で代入するときに使われる。」と書きました。
「オブジェクトを「同じ型の別のオブジェクト」で代入するとき」とは、どのようなときかというと、
オブジェクトが関数に値渡しされるときに呼び出されるとき。
があります。
下にコピーコンストラクタを用いてオブジェクトを関数に値渡ししたときのサンプルコードを示します。
下のサンプルコードで関数 testFunc はWidget 型の引数を値で受け取る関数です。
実行結果を見ると、関数が呼ばれた際にコピーコンストラクタが呼ばれていることが分かる。
このように、コピーコンストラクタは、関数でオブジェクトが値渡しされる際に呼び出されます。
前回、コメントで教えて頂いたのですが、コピーコンストラクタにexplicitを付けると、コンパイルエラーになることが分かります。
これは、関数の値渡しの際に暗黙の型変換が行われているためです。
なぜかというと、
値渡しは、関数内で新しくオブジェクトを生成する必要があるため、
Widget w = a // (a はmainで生成した Widget 型のオブジェクト)
このように、暗黙の型変換が行われるためです。
サンプルコード
# 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; };
};
void testFunc(Widget w) { std::cout << __func__ << " : " << __LINE__ << std::endl; };
int main(int argc, char* argv[]) {
std::cout << "intro_default_constructor4.cpp" << std::endl;
Widget a(1); // コンストラクタ
testFunc(a); // コピーコンストラクタが呼ばれる
}
実行結果
参考文献
・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0