1
#include <iostream>
using namespace std;

class ClassA {
    int k;
public:
    ClassA(int i) : k(i) 
    {
    }

    ~ClassA()
    {
        cout << "A destroyed" << " k=" << k << endl;
    }

    ClassA copyAndModify() 
    { 
        ClassA a(k*2);
        return a; 
    }

    void taunt() 
    {
        cout << k << endl;
    }
};

int main (int argc, char * const argv[]) {
    ClassA original(1)
    ClassA modified = original.copyAndModify();
    modified.taunt();
    return 0;
}

オブジェクト「a」(メソッドcopyAndModify内)は、メソッドが戻ったときに分解されたと思いましたが、そうではありませんでした。これは、メソッド内で作成され、返されるすべてのオブジェクトが分解されないことを意味しますか?これはすべてのコンパイラに当てはまりますか?

4

4 に答える 4

7

戻り値の最適化に遭遇しました。いいえ、すべてのコンパイラで同じになるわけではありません。

于 2012-04-20T23:05:16.713 に答える
1

これはコンパイラーによって異なりますが、通常、メソッドがオブジェクトインスタンスを値で返す場合、コンパイラーはRVO(戻り値の最適化)を使用して、宛先オブジェクトを非表示の参照パラメーターとして渡すことにより、一時的なものがまったく作成されないようにします。つまり、コンパイラーは、生成されたコードを微調整して、コードを次のように記述したように動作させます。

void copyAndModify(ClassA &result)
{  
    ClassA a(k*2); 
    result = a;  
} 

ClassA modified;
original.copyAndModify(modified); 
于 2012-04-20T23:09:12.970 に答える
0

VSの場合、デバッグモードでビルドすると、最適化は行われません(オブジェクトは破棄されます)が、リリースモードでは最適化が開始されます(オブジェクトは破棄されません)。

于 2012-04-20T23:12:42.613 に答える
-1

そのとおりです。返却された場合、破壊されません。それは理にかなっている。すでに破壊されたオブジェクトを返すことは意味がありません。

于 2012-04-20T23:05:58.337 に答える