コピーコンストラクタ/代入演算子周りのメモ

いつも書く時には忘れてて、そのたびに簡単なサンプルコード書いてるのでいい加減メモっておく。代入演算子の多重定義(オーバーロード)の際にはセオリー通りreturn *thisでオブジェクトの参照を返すのも忘れないようにする。挙動のまとめとしては

  • Hoge x:デフォルトコンストラクタ呼び出し
  • Hoge a = x:コピーコンストラクタ呼び出し
  • Hoge a(x):コピーコンストラクタ呼び出し
  • a = x:代入演算子呼び出し

ってこと。特にHoge a = xの時に代入演算子じゃなく「コピーコンストラクタ」が出てくる点に注意。あと関数側に値渡しした際にも当然コピーコンストラクタが発動する。

以下、サンプルコード

#include<iostream>

//適当なサンプルクラス
class Hoge
{
public : 
	//デフォルトコンストラクタ
	Hoge() : y_(0){
		std::cout << "Constructor" << std::endl;
	}
	//コピーコンストラクタ
	Hoge(const Hoge & x) : y_(x.y_){
		std::cout << "Copy constructor" << std::endl;
	}
	//=演算子の多重定義
	Hoge& operator = (const Hoge &x){
		std::cout << "Equal operator" << std::endl;
		return*this;
	}
	//setter & getter
	void SetValue(int y){
		y_ = y;
	}
	int GetValue(){
		return y_;
	}
private : 
	int y_;
};

//値を表示する関数(値渡しと参照渡しの2ケース)
void ShowValueByValue(Hoge x)
{
	std::cout << "Value : " << x.GetValue()<< std::endl;
}
void ShowValueByReference(Hoge &x)
{
	std::cout << "Value : " << x.GetValue()<< std::endl;
}

int main()
{
	//デフォルトコンストラクタ
	Hoge x;
	//コピーコンストラクタが呼ばれる
	Hoge a(x);
	std::cout << std::endl;

	//代入演算子が呼ばれる
	x = a;
	//(代入に見えるけど初期化なので)代入演算子ではなくコピーコンストラクタが呼ばれる
	Hoge b = x;
	std::cout << std::endl;

	//コピーコンストラクターによってオブジェクトをコピーしてから値を表示
	ShowValueByValue(a);
	//コピーなしでそのまま値を表示
	ShowValueByReference(a);
	std::cout << "end" << std::endl;

	return 0;
}

実行結果は上のプログラムでコメント書きした想定通りになる。

Constructor
Copy constructor

Equal operator
Copy constructor

Copy constructor
Value : 0
Value : 0
end