2016-06-01 5 views
4

私は、そのオブジェクトの戻り値の型を持つ関数内のオブジェクトへの参照を返すときに、何が起こるのかを明確にしたいと考えています。C++:参照で値を返す

は、次の関数考えてみます。

CObject getObject() { 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 

を「localObjectに」への参照を返すとは対照的に、この関数は、「localObjectに」のコピーを返すことを私の理解です。これは正しいです?基本的には、localObjectをコンストラクタパラメータとして使用して新しいオブジェクトを作成して返しますか? 例えば、

CObject newObject(localObject); 
+0

ヒープ上のスタックを実行する... –

+0

ヒープが必要な場合は、ヒープを実行してください。 –

答えて

6

は、それはあなたのオブジェクトのコピーを返します。ただし、関数の宣言を変更して参照を返す場合は、コードの結果が未定義の動作になることに注意してください。

例:

class CObject{ 
    public: 
    CObject(){std::cout << "cosntructing ";} 
    CObject(const CObject& other){std::cout << "copying ";} 
}; 

CObject getObject(){ 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 

int main(){ 
    auto result = getObject(); 
} 

これはになります:

コピー

cosntructing

:あなたのコンパイラがある場合は、同じ結果が得られないことをRVOによるコードの最適化。だからすべての最適化をオフにしてみてください。 @Caduchonは、最適化がなくても、コピーエリートによって結果が変わる可能性があると述べています。 未定義の動作と機能の


例:

CObject& getObject() { 
    CObject localObject; 
    CObject &objectRef(localObject); 
    return objectRef; 
} 
+0

結果が新しい変数に割り当てられている場合は、コピーを省略できます。コンパイラはそれを見ることができ、関数から変数を直接構築することができます。 – Caduchon

+0

@Caduchonあなたは私よりも速かった:)それは編集された。私は参照していただきありがとうございます –

+1

を参照してください。したがって、戻り値の型が値である限り、参照によって与えられているオブジェクトのコピーが常に作成されます。徹底的な答えをありがとう! – Ludus

1

あなたはそれがローカルオブジェクトへの参照を返していないことが正しいです。実際に返される内容に関しては、答えは少し微妙です。 return value optimisationと呼ばれるもののため、コンパイラは実際には関数の呼び出しの結果としてCObjectのインスタンスを1つだけ作成します。基本的に元のlocalObjectが呼び出し関数によって直接使用できるように構築されていることを意味する最適化の仕組みです。したがって、呼び出しの戻り時にコピーの構築は必要ありません。