C++と色々

主にC++やプログラムに関する記事を投稿します。

テンポラリオブジェクトの寿命

自分がテンポラリオブジェクトの寿命と参照、右辺値参照をちゃんと理解していないため色々試してみる。
値を代入する場合、右辺値と関数の戻り値ではデストラクトされるタイミングが違うみたい?

#include <iostream>
using namespace std;

void Section(int n)
{
	cout << endl << "Section:" << n <<endl;
}

class Hoge
{
	int num;
	static int count;
public:
	explicit Hoge(int n) : num(n) { cout << "Hoge" << " num:" << num << " count:" << ++count << endl; }
	Hoge(const Hoge& rhs) : num(rhs.num) { cout << "Hoge" << " num:" << num << " count:" << ++count << endl; }
	Hoge& operator = (const Hoge& rhs) { num = rhs.num; cout << "Hoge=" << " num:" << num << " count:" << count << endl; return *this;}
	~Hoge() { cout << "~Hoge" << " num:" << num << " count:" << --count << std::endl; }
};

int Hoge::count;

const Hoge& f(int n)
{
	return Hoge(n);
}

int main()
{
	Section(0);
	Hoge h1(1);
	h1 = Hoge(10);//テンポラリオブジェクトは代入してから破壊されている

	Section(1);
	Hoge h2(2);
	h2 = f(20);//テンポラリオブジェクトが破壊されてから代入している

	Section(-1);
	return 0;
}

実行結果

Section:0
Hoge num:1 count:1
Hoge num:10 count:2
Hoge= num:10 count:2
~Hoge num:10 count:1

Section:1
Hoge num:2 count:2
Hoge num:20 count:3
~Hoge num:20 count:2
Hoge= num:-858993460 count:2

Section:-1
~Hoge num:-858993460 count:1
~Hoge num:10 count:0
続行するには何かキーを押してください . . .

他に、const参照だとテンポラリオブジェクトの寿命がそのconst参照と同じ所まで伸びる場合があるらしい

#include <iostream>
using namespace std;

void Section(int n)
{
	cout << endl << "Section:" << n <<endl;
}

class Hoge
{
	int num;
	static int count;
public:
	explicit Hoge(int n) : num(n) { cout << "Hoge" << " num:" << num << " count:" << ++count << endl; }
	Hoge(const Hoge& rhs) : num(rhs.num) { cout << "Hoge" << " num:" << num << " count:" << ++count << endl; }
	Hoge& operator = (const Hoge& rhs) { num = rhs.num; cout << "Hoge=" << " num:" << num << " count:" << count << endl; return *this;}
	~Hoge() { cout << "~Hoge" << " num:" << num << " count:" << --count << std::endl; }
};

int Hoge::count;

const Hoge& f(int n)
{
	return Hoge(n);
}

int main()
{
	Section(0);
	const Hoge& h1 = Hoge(0);//テンポラリオブジェクトの寿命はh1の寿命と同じ(=寿命が伸びてる!)

	Section(1);
	const Hoge& h2 = f(1);//関数の戻り値は基本通り、完結式までが寿命

	Section(-1);
	return 0;
}

実行結果

Section:0
Hoge num:0 count:1

Section:1
Hoge num:1 count:2
~Hoge num:1 count:1

Section:-1
~Hoge num:0 count:0
続行するには何かキーを押してください . . .

例外があるとうっかりミスしそうで怖い…

参考文献
ロベール:"ロベールのC++入門講座"、毎日コミュニケーションズ(2007)
"C++と組み込み環境":http://cppemb.blog17.fc2.com/blog-entry-49.html(2012/6/17アクセス)