我正在写一个使用句柄的库的小包装。C++移动运营商类成员
这个库的基本用途是:
int handle;
createHandle(1, &handle)
doSomethingWithHandle(handle);
// ...
destroyHandle(handle);
我做了一个包装类以下RAII原则:
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
它的工作,但是,很多一类依赖于这些包装,这意味着每次有一个类有句柄成员时,我必须明确地写出移动构造函数/移动赋值操作符:
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;
}
这当然不难,但我不知道是否有办法避免这种情况,因为那样会产生大量冗余代码。
如果这是不可能的,为什么移动操作符不是由编译器生成的?让我们以下面几行:
SomeClass a;
m_vector.push_back(a);
在这种情况下,SomeClass的是不可拷贝,是因为a.m_handle已复制经营删除编译器将有一个错误。所以这意味着我们必须移动它们。但是,如果我们这样做,难道不是因为我们想要移动每个成员(如果我们不能复制它们)吗?
编辑:我只是尝试了一些东西,它似乎工作,只声明移动运营商使用默认值。这是我想去的路。但“为什么”的问题依然存在。
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();
}
请显示[MCVE](/帮助/ MCVE),其中包括SomeClass'的'休息。通常,Handle不应该阻止生成默认的移动赋值运算符和构造函数。 – MikeMB
您可以按照零规则设计类(编译器生成的复制/移动构造函数,复制/移动赋值运算符和析构函数) –
您可以使用['std :: unique_ptr'](http ://en.cppreference.com/w/cpp/memory/unique_ptr)与一个调用'destroyHandle()'的定制删除程序。 –