2013-08-10 1 views
10

나는 인터넷을 검색했고, 이동 생성자 정의의 3 가지 방법을 발견 :이동 생성자를 올바르게 정의하는 방법은 무엇입니까?

T(T&& other) = default; 
  • 역 참조 this 포인터 :

    T(T&& other) { 
        *this = std::move(other); 
    } 
    
  • 가 명시 적으로 재 할당을 컴파일러에 의존

    1. 을 전체 회원 :

      T(T&& other) { 
          T.a = other.a; 
          T.b = other.b; 
          //... 
      } 
      

    어느 것이 적절한 방법입니까? (그리고 심지어 정확한 번째입니까?)

  • +3

    둘째는 올바르지 않습니다 (일반적으로 존재하지 않는 개체는 참조 할 수 없음). 세 번째 것은 바보입니다. –

    +0

    @KerrekSB MSDN 웹 사이트에서 두 번째 것을 찾았습니다. http://msdn.microsoft.com/en-us/library/dd293665.aspx 어쩌면 MSVC가 지원합니다 .. GCC에 대해 확실하지 않습니다 – texasbruce

    +0

    해당 페이지에서 세 번째를 찾았습니다. 너무 ... – texasbruce

    답변

    15

    적절한 일반적인 방법은 각 멤버를 이동-구축하는 것입니다, 그러나 그것은 defauted 버전 어쨌든 무엇이다 :

    거친 원칙적으로
    T(T && rhs) 
    : a(std::move(rhs.a)) 
    , b(std::move(rhs.b)) 
    { } 
    

    , 당신은 사용해야합니다 기본 정의는 당신이 필요로하는 모든 경우에, 당신은 전직 당신이 전 ­ PLI ­ citly 구현은 고유의 소유권 자원 관리자로, 의미를 이동 일을하는 경우 ­ PLI ­ CIT 이동 생성자를 작성해야 :

    URM(URM && rhs) 
    : resource(rhs.resource) 
    { 
        rhs.resource = nullptr; 
    } 
    

    이 클래스가 적절한 지 여부를 나타내는 표시기는 아마도 사용자 클래스가 ­ 구조체 (­ 사용자 정의)를 가지고 있는지 여부입니다. 이 예제에서 소멸자는 관리 자원을 해제 할 것이므로 한 번만 수행해야하므로 이동 된 객체를 수정해야합니다.


    이 관련이 있지만, 대입 연산자를 언급하고 있기 때문에, 여기에 인기 스왑 앤 할당/스왑 관용구이다 :

    void swap(URM & rhs) noexcept  // assume members are noexcept-swappable! 
    { 
        using std::swap; 
        swap(resource, rhs.resource); 
        // ... 
    } 
    
    URM & operator=(URM rhs) noexcept // pass by value 
    { 
        rhs.swap(*this); 
        return *this; 
    } 
    

    이 방법의 장점은 하나만 필요하다 적절할 때 이동 구성을 사용하여 임시 및 비 임시로 모두 작동하는 할당 연산자의 단일 버전입니다. 모든 구성원이 잘 설계되어있는 한 하나의 단일 swap 함수 만 있으면됩니다. 그 외에, 잘 설계된 클래스가 허용해야하는 스왑 함수가 발생하지 않으면 가능한 모든 예외가 이미 호출 사이트에서 발생하기 때문에 할당 연산자가 throw되지 않습니다.

    +0

    예를 들어,'resource'이'std :: unique_ptr'이라면 마지막으로 정말로 필요합니까? –

    +3

    @JoachimPileborg : 아니요. 예제는 'unique_ptr'의 * 구현 * 일 수 있습니다. –

    +0

    기본 설정은 어떻습니까? 나는 그것을 전혀 안전하게 사용할 수 있습니까? – texasbruce

    1
    T(T&& other) 
    : data(0) // initialize members 
    { 
        swap(other); // where the class has a member function swap or std::swap(this->data, other.data) 
    } 
    
    관련 문제