ゲームが作れるようになるまでがんばる日記

ゲーム制作のことを中心にゲームに関することを書いています

オブジェクトを戻すときに参照で戻すな

Effective C++ 第4章21項
値渡しよりも参照渡しのほうが効率が良いからといって、ある関数での戻り値をすべて参照にすればいいわけではない。クラスのメンバ変数なら関数を抜けたあとも存在しているから良いが、ローカル変数の場合は関数を抜けると破棄されてしまう。例えば次のようなコード。

// 間違ったコード
const Test& func()
{
    Test a;
    return a;
}

ここでのTestクラスのオブジェクトaは関数を抜けると破棄されるので、関数を呼び出した側で受け取っても有効ではない。
では、次のコードのようにnewで確保すれば関数を抜けても存在している。しかしこちらも良くないコード。

// 間違ったコード
const Test& func()
{
    Test *a = new Test();
    return *a;
}

この関数を次のように呼び出したらdeleteすることが出来ないオブジェクトが出来てしまう。

Test b = func() + func(); // Testクラスにoperator+が定義されているとする

参照ではなく普通に戻してやれば良い。

Test func()
{
    Test a;
    return a;
}

ローカル変数で関数を抜けるときに破棄されるが戻り値は値渡しでコピーされるので関数を呼び出した側で正しく使用することができる。