我正在寫一個使用句柄的庫的小包裝。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()'的定製刪除程序。 –