3

このページは奇妙なことを言っています:-

一時的なものは、プログラムが戻り値をオブジェクトにコピーしない場合にのみ作成され、例は次のとおりです。

UDT Func1(); // Declare a function that returns a user-defined type.
            ...

Func1();        //  Call Func1, but discard return value.
               //  A temporary object is created to store the return
              //   value

しかし、私がやった場合:-

UDT obj=Fuct1;

次のように一時的なものも作成されるように思われます:-

Func()ローカルオブジェクトを構築します。次に、このローカルオブジェクトは呼び出し元のスタック上でコピー構築され、temporary objectobjのコピーコンストラクターの引数として使用されるを作成します。

私が間違っている?
これはコピーの省略と関係がありますか?

4

3 に答える 3

5

あなたが引用するページは、特定のコンパイラの振る舞いの説明です。正式には、戻り値は常に一時的なものです。その一時がコピーコンストラクターの引数として使用される(オブジェクトがコピーされる)コンテキストでは、標準はコンパイラーにコピーを削除する明示的な許可を与え、一時を初期化する名前付き変数と「マージ」します。あなたが引用しているすべての文は、この特定のコンパイラが常に最適化を行うということです(他のほとんどのコンパイラと同じように)。

于 2012-01-27T08:35:52.870 に答える
4

このページはMicrosoft固有です。確かに、標準では、関数の戻り中にコピーコンストラクターに対して2回、1回、または0回の呼び出しを行うことが許可されています(これはコピーの省略と呼ばれます)。実際、1回の呼び出しで常に十分です。

あなたが書いたとしましょう:

A f(int x) {
    return A(x);
}

void g() {
    A r = f(10);
}

MSVCがこれを実装する方法は次のとおりです。

void f_impl(A* r, int x) {
    new((void*)r) A(x); // construct the return value into r
}

void g_impl() {
    A r = __uninitialized__;
    f_impl(&r, 10);
}

ここでは、コピーコンストラクターへの呼び出しはゼロであり、一時的なものはありません。

あなたがfこのように呼ぶならば:

void g() {
    f(10);
}

次に、コンパイラはまだどこかに戻り値を作成する必要があるため、一時的なものを作成します。

void g_impl() {
    A r = __uninitialized__;
    f_impl(&r, 10);
    r.~A(); // destruct temporary
}

コピーコンストラクターを呼び出すときは?の実装では、どのローカルが返されるfかわからない場合。f例:

A f(int x)
{
    A r1;
    A r2;
    // ...do something complicated modifying both r1 and r2...
    if(x)
        return r1;
    // ...do something complicated...
    return r2;
}

次のようなものに翻訳されます:

void f_impl(A* r, int x)
{
    A r1;
    A r2;
    // ...do something complicated modifying both r1 and r2...
    if(x)
    {
        new((void*)r) A(r1); // copy construct r1
        return;
    }
    // ...do something complicated...
    new((void*)r) A(r2); // copy construct r2
}
于 2012-01-27T08:32:42.463 に答える
0

戻り値は常に一時的なものです。2番目のケースでは、コピーの省略が発生しない場合、その一時的なコピー(C ++ 11で移動)が作成されます。

于 2012-01-27T05:38:42.203 に答える