我有一个代码库,我想从C++ 03切换到C++ 11.
据我所知,一些类将通过隐式默认移动构造函数(以及随之而来的移动赋值运算符)从更改中受益.虽然我对此完全没问题(我甚至认为这是一件好事)但我有点害怕这些隐式构造函数可能对我所拥有的一些非可复制类产生的影响.
我拥有的一个例子是一个包含iconv_t句柄libiconv以利用RAII的类.
更明确地说,课程如下:
class iconv_wrapper
{
public:
iconv_wrapper() : m_iconv(iconv_open()) {}
~iconv_wrapper() { iconv_close(m_iconv); }
private:
// Not implemented: non copyable. Should probably be = delete; in C++11.
iconv_wrapper(const iconv_wrapper&);
iconv_wrapper& operator=(const iconv_wrapper&);
iconv_t m_iconv;
};
Run Code Online (Sandbox Code Playgroud)
我担心的是:如果这个类的实例碰巧被移动,这将导致双重调用iconv_close().作为iconv_t一个"哑"整数类型,我不希望默认实现iconv_wrapper(iconv_wrapper&&)使m_iconvR值的成员无效.即使它确实如此,也没有实现析构函数来正确处理它.
所以我的问题是:
std::unique_ptr但我不能很好地工作,因为它需要一个指针,而不是一些不透明的类型)它不会被移动.因为您有一个用户声明的复制构造函数,复制赋值运算符和析构函数,所以不会生成移动构造函数和移动赋值运算符.实际上,这三个声明中的任何一个都会抑制自动生成移动构造函数和移动赋值运算符.
如果你想让它更友好,你可以添加一个移动构造函数和移动赋值运算符,如(警告:从未编译或测试):
class iconv_wrapper
{
public:
iconv_wrapper() : m_iconv(iconv_open()) {}
~iconv_wrapper() { if ((iconv_t)-1 != m_iconv) iconv_close(m_iconv); }
iconv_wrapper(iconv_wrapper&& that) noexcept { std::swap(m_iconv, that.m_iconv); }
iconv_wrapper& operator=(iconv_wrapper&& that) noexcept { std::swap(m_iconv, that.m_iconv); return *this; }
private:
iconv_t m_iconv = (icontv_t)-1;
};
Run Code Online (Sandbox Code Playgroud)
您可能希望这样做的原因是您可以将这些对象(或包含这些对象的其他类型)存储在向量中.