2017-11-07 4 views
0

私は移動コンストラクタが呼び出されていることを保証しようとしているコード移動コンストラクタへの呼び出しをどのように確実にする必要がありますか? (意味論と右辺値参照を動かす)

#include <iostream> 
#include <vector> 

using namespace std; 

class ArrayWrapper { 
    private: 
     int *_p_vals; 
     int _size; 

    public: 
     //default constructor 
     ArrayWrapper() : _p_vals(new int[ 64 ]) , _size(64) { 
      cout << "default constructor called\n"; 
     } 

     //constructor 2 
     ArrayWrapper (int n) : _p_vals(new int[ n ]) , _size(n) { 
      cout << "constructor 2 called\n"; 
     } 

     //move constructor 
     ArrayWrapper (ArrayWrapper&& other) : _p_vals(other._p_vals), _size(other._size) { 
      cout << "move constructor called\n"; 
      other._p_vals = nullptr; 
      other._size = 0; 
     } 

     // copy constructor 
     ArrayWrapper (const ArrayWrapper& other) : _p_vals(new int[ other._size ]) , _size(other._size) { 
      cout << "copy constructor called\n"; 
      for (int i = 0; i < _size; ++i) 
       _p_vals[i] = other._p_vals[i]; 
     } 

     ~ArrayWrapper() { 
      delete [] _p_vals; 
     } 

     void set_val (std::initializer_list <int> vals) { 
      int i = 0; 
      for (auto val : vals) { 
       _p_vals[i] = val; 
       i++; 
      } 
     } 
     void print_val() const { 
      for (auto i = 0; i < _size ; i++){ 
       cout <<_p_vals[i] << ":" ; 
      } 
      cout << endl; 
     } 
}; 

ArrayWrapper getArrayWrapper() { 
    ArrayWrapper A(5); 
    A.set_val({1,2,3,4,5}); 
    return A; 
} 

int main() { 
    ArrayWrapper arr {getArrayWrapper()}; 
    arr.print_val(); 
    return 0; 
} 

のこの作品を持っています。しかし、いくつかのデフォルトのコピーコンストラクタは、出力は単にこの

constructor 2 called 
1:2:3:4:5: 

あるので、私は、次のグラムを使用しています使用されている++バージョン

g++ (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406 

は、私はすべてのコンストラクタはexplicitを呼び出して行う必要があります。それがどのように役立つだろうかと思う。上に書いた移動コンストラクタとコピーコンストラクタをプログラムに強制的に呼び出させる方法はありますか?

+1

参照渡しは決して移動コンストラクタを使用せず、ローカルオブジェクトへの参照を返すことは決して正確ではありません。移動セマンティクスを使用してローカルオブジェクトを戻すには、代わりに値で戻します。 https://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variableを参照してください –

+0

ローカル変数への参照を返すことはできません。右辺値かどうかは関係ありません。関数が終了すると参照するものはありません。 – NathanOliver

+0

重複がありますか? https://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion-return-statement –

答えて

0

コメント者のおかげで、コンパイラが上記のコンストラクタへの呼び出しを防ぐ戻り値最適化(RVO)を行っていることが分かりました。私はRVOを無効にする方法を見つけました。 g ++のスイッチ-fno-elide-constructorsが機能します。

関連する問題