2017-11-07 13 views
0

나는 이동 생성자가 호출되고 있음을 보장하기 위해 노력하고 코드이동 생성자에 대한 호출을 어떻게 보장해야합니까? (의미와를 rvalue 참조를 이동)

#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를 호출을해야 내가 ++ 버전을 다음 g을 사용하고 사용하고 있습니다. 그게 어떻게 도움이 될지 궁금해. 위에서 작성한 이동 생성자와 복사 생성자를 프로그램에서 강제로 호출 할 수있는 방법이 있습니까? 덧글에

+1

결코 이동 생성자와 로컬 개체에 대한 참조를 반환하는 것은 결코 올바른을 사용하지 않습니다. 이동 의미를 사용하여 로컬 객체를 반환하려면 값 대신 반환하십시오. https://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable를 참조 –

+0

당신은 지역 변수에 대한 참조를 반환 할 수 없다. 그것이 rvalue reference인지 아닌지는 중요하지 않습니다. 함수가 끝나면 참조 할 것이 없습니다. – NathanOliver

+0

중복 가능성이 있습니까? https://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion-return-statement –

답변

0

덕분에, 나는 컴파일러는 위의 기록 생성자에 대한 호출을 방지 반환 값 최적화 (RVO)을하고있는 것을 발견했다. RVO를 비활성화하는 방법을 찾았습니다. g ++에서 -fno-elide-constructors 스위치가 작동합니다. 참조로 반환