0

私の理解ではTest、この関数は値で返されるため、以下のコードはクラスのムーブ コンストラクターを呼び出すGetTestObj()必要があります。

class Test
{
  public:
         Test()
         {
         }
         Test(const Test& arg)
         {
            std::cout<<"Copy Constructor Called..."<<std::endl;
         }
         Test(Test&& arg)
         {
            std::cout<<"Move Constructor Called..."<<std::endl;
         }
};

Test  GetMyTestObj()
{
      Test *ptr = new Test();
      return *ptr;
}
Test dummy = GetMyTestObj(); //Copy Constructor Called...
4

3 に答える 3

2

コードには、実際には から へのコピーが 1 つと、 からへ*ptrの移動が 1 つあります。ただし、コンパイラは移動を無視するため、トレースは表示されません。GCC または Clang に渡すと、コピーと移動 ( demo ) が表示されます。GetMyTestObj()dummy-fno-elide-constructors

戻り値の構造を移動する場合は、次を使用する必要がありますstd::move

Test GetMyTestObj()
{
      Test *ptr = new Test();
      return std::move(*ptr);
}

ただし、この場合、動的割り当てはまったく必要ありません。非効率的であり、実装でメモリ リークが発生します。自動変数を使用する必要があります。

Test GetMyTestObj()
{
    Test test;
    //I assume you're doing something else here
    return test;
}

上記のコードでは、コンパイラは実際に両方の構造を省略できます。

その関数で他に何もしていない場合は、dummy直接構築する必要があります。

Test dummy{};
于 2016-11-07T08:37:01.903 に答える
0

値はここにコピーされません (コピー省略のため、コンストラクターは呼び出されません):

Test dummy = GetMyTestObj();

しかし、ここで:

return *ptr;

関数は左辺値参照から右辺値オブジェクトを作成する必要があるためです。基本的に、GetMyTestObj()この場合の関数は次と同等です。

Test *ptr = new Test();
Test returnValue(*ptr);
return returnValue;
于 2016-11-07T08:38:46.357 に答える