-2

重複
の可能性: コピー コンストラクターを呼び出さない

このコードでは、コピー コンストラクターは呼び出されません (ムーブ コンストラクターや代入演算子も呼び出されません)。それはどのように可能ですか?関数が値を返す方法、スタックとレジスタで何が起こるかを誰かが説明できますか (または良いリンクを投稿してください)。

    #include <iostream>
#include <cstring>

using namespace std;

class Test;

Test getnew(int arg);
class Test
{

  public:
    char *conts;
    int len;
        Test(char* input = NULL){conts = new char[len=10];
            if(input)strncpy(conts,input,9);else strcpy(conts,"xxxxx");
            cout << "\nconstructor: " << conts;
        };
        Test(const Test& t){
                conts = new char[10];
                if(t.len)strncpy(conts,t.conts,9);
                len = t.len;
                cout << "\ncopy-constructor: " << conts;
        };
        Test(Test&& t){
               conts = t.conts;
               t.conts = NULL;
               std::swap(len,t.len);
               cout << "\nmove-constructor: " << conts;
        };

        ~Test(){
            cout << "\ndestructor";
            if(conts)delete [] conts;
             len = 0;
             conts = NULL;
        };
        Test& operator=(Test rhs)
        {
            std::swap(conts,rhs.conts);
            std::swap(len,rhs.len);
            cout << "\nassigend: " << conts;
        }

};

int main()
{

   Test t2 = getnew(1);
   cout << endl << t2.conts;
    return 0;
}

Test getnew(int arg)
{
        Test retj("FFFFF");
        return retj;
}

1 つのコンストラクタと 1 つのデストラクタのみが呼び出されます。しかし、オブジェクト t2 には、正しい値 "FFFF" で初期化された値メンバー conts があります。戻り値の最適化が適用されることは知っていますが、オブジェクト t2 はどのように初期化されるのでしょうか?

4

2 に答える 2

4

理論的には、コンパイラが戻り値の一時コピーを作成し、その一時オブジェクトが関数の出力を受け取る変数に割り当てられるはずです。

ただし、コンパイラは、コピー コンストラクターまたはムーブ コンストラクターに副作用があっても、戻り値のコピーおよびムーブを省略できます。あなたの場合、これはいわゆるNRVO (Named Return Value Optimization) に変わります。これはRVO (Return Value Optimization) の特殊なケースです。

したがって、表示されているのは移動省略の結果である可能性が非常に高くなります。この最適化を無効にするコンパイラ オプションがありますが、一部のコンパイラ (Clang 3.2 など) には、これらのオプションを処理するバグがあります (この質問への回答を参照してください)。

于 2013-01-20T16:53:34.137 に答える
0

戻り値の最適化を使用して、で初期化されたオブジェクトT2に割り当てられます。それがRVOの仕組みです。Testgetnew

于 2013-01-20T16:49:23.343 に答える