繁体   English   中英

将代码从C ++ 03迁移到C ++ 11:我应该对隐式默认移动构造函数保持谨慎吗?

[英]Migrating code from C++03 to C++11: should I be cautious about the implicit default move constructor?

我有一个代码库,我想从C ++ 03切换到C ++ 11。

据我所知,一些类将通过隐式默认移动构造函数(以及随之而来的移动赋值运算符)从更改中受益。 虽然我对此完全没问题(我甚至认为这是一件好事)但我有点害怕这些隐式构造函数可能对我所拥有的一些非可复制类产生的影响。

我有一个例子是从libiconv包装iconv_t句柄以利用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;
};

我担心的是:如果碰巧移动了这个类的实例,这将导致对iconv_close()的双重调用。 由于iconv_t是一个“哑”整数类型,我不希望iconv_wrapper(iconv_wrapper&&)的默认实现使R值的m_iconv成员无效。 即使它确实如此,也没有实现析构函数来正确处理它。

所以我的问题是:

  • 我的担忧是否合法? 我是对的,在这种情况下,默认的可移动构造函数/运算符=是不正确的吗?
  • 我可以对C ++ 11很好地移植这段代码做些什么改变? (我被建议使用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;
};

您可能希望这样做的原因是您可以将这些对象(或包含这些对象的其他类型)存储在向量中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM