2016-06-26 6 views
0

핸들을 사용하는 라이브러리 주위에 작은 래퍼를 쓰고 있습니다. 이 라이브러리의C++ 이동 연산자 클래스 멤버

기본 용도는 : 제대로 작동

Handle::Handle() 
{ 
    createHandle(1, &m_handle); 
} 

Handle::~Handle() 
{ 
    if(m_handle!= 0) 
     destroyHandle(m_handle); 
} 

Handle::Handle(Handle&& h) : 
    m_handle(h.m_handle) 
{ 
    h.m_handle = 0; 
} 

Handle& Handle::operator=(Handle&& h) 
{ 
    m_handle = h.m_handle; 
    h.m_handle = 0; 
    return *this; 
} 

// copy constructor and copy assignment operator are explicitely deleted 

그러나, 많은 클래스를 의미하는 래퍼에 따라 달라집니다

int handle; 
createHandle(1, &handle) 
doSomethingWithHandle(handle); 
// ... 
destroyHandle(handle); 

내가 RAII 원칙을 다음과 래퍼 클래스를 만든 클래스에 핸들 멤버가있을 때마다 명시 적으로 이동 생성자/이동 대입 연산자를 써야합니다.

SomeClass::SomeClass(SomeClass&& s) : 
    m_handle(std::move(s.m_handle)) 
{ 

} 

SomeClass& SomeClass::SomeClass(SomeClass&& s) 
{ 
    m_handle = std::move(s.m_handle); 
    return *this; 
} 

이것은 물론 어렵지는 않지만 중복 코드가 많기 때문에이를 피할 수있는 방법이 있는지 궁금합니다.

그럴 수 없다면 왜 컴파일러는 이동 연산자를 생성하지 않습니까? 의 다음 줄을 보자 : a.m_handle가 복사 운영자가 삭제 한 때문에 컴파일러 오류가있을 것이다이 경우에

SomeClass a; 
m_vector.push_back(a); 

이 someclass가 복사 가능한 없습니다. 그래서 우리가 그들을 움직여야 함을 의미합니다. 그러나 우리가 그렇게한다면, 우리는 모든 회원들을 (우리가 그들을 복사 할 수 없다면) 옮기고 싶습니다.

편집 : 방금 무언가를 시도했지만 제대로 작동하는 것 같습니다. 기본값을 사용하여 이동 연산자를 선언하십시오. 이것은 제가 가야 할 길입니다. 그러나 "왜"문제가 남아 있습니다.

Edit2가 : 또 다른 예를 들어 내가 명시 적으로 생성자/이동 할당 연산자를 이동 작성해야

class Test 
{ 
public: 
    Test() 
    { 
     m_vec.resize(10); 
    } 

    Test(const Test&) = delete; 
    Test& operator=(const Test&) = delete; 

    //Test(Test&&) = default; 
    //Test& operator=(Test&&) = default; 

    void cout() 
    { 
     std::cout << m_vec.size() << std::endl; 
    } 

private: 
    std::vector<int> m_vec; 
}; 

int main() 
{ 
    Test a; 

    std::vector<Test> v; 
    v.push_back(std::move(a)); 

    v[ 0 ].cout(); 
} 
+0

이 SomeClass''의 나머지 부분을 포함하는 [mcve] (/ 도움말/mcve)를 보여주십시오

SomeClass a; m_vector.push_back(a); 

당신은 잘못, 그것이어야했다. 일반적으로 Handle은 기본 이동 지정 연산자 및 생성자의 생성을 막아서는 안됩니다. – MikeMB

+0

0의 규칙에 따라 클래스를 디자인 할 수 있습니다 (컴파일러에서 생성 된 복사/이동 생성자, 복사/이동 할당 연산자 및 소멸자) –

+0

사용자 정의 래퍼를 작성하는 대신 ['std :: unique_ptr'] (http : //en.cppreference.com/w/cpp/memory/unique_ptr)에'destroyHandle()'을 호출하는 커스텀 Deleter가있다. –

답변

0

: 당신이 잘못 곳

이다. 둘 모두를 쓰지 말고 컴파일러 또는 =default;을 사용하십시오.

SomeClass a; 
m_vector.push_back(std::move(a)); 
+0

"이 경우 someclass를 복사 할 수 없으므로 a.m_handle에 복사 연산자가 삭제되어 컴파일러에서 오류가 발생합니다." 나는 그것을 알고 있지만, 나는 이것이 가난하게 말한 것에 동의한다. – Aulaulz