핸들을 사용하는 라이브러리 주위에 작은 래퍼를 쓰고 있습니다. 이 라이브러리의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();
}
이 SomeClass''의 나머지 부분을 포함하는 [mcve] (/ 도움말/mcve)를 보여주십시오
당신은 잘못, 그것이어야했다. 일반적으로 Handle은 기본 이동 지정 연산자 및 생성자의 생성을 막아서는 안됩니다. – MikeMB0의 규칙에 따라 클래스를 디자인 할 수 있습니다 (컴파일러에서 생성 된 복사/이동 생성자, 복사/이동 할당 연산자 및 소멸자) –
사용자 정의 래퍼를 작성하는 대신 ['std :: unique_ptr'] (http : //en.cppreference.com/w/cpp/memory/unique_ptr)에'destroyHandle()'을 호출하는 커스텀 Deleter가있다. –