简体   繁体   English

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

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

I have a codebase that I'd like to switch from C++03 to C++11. 我有一个代码库,我想从C ++ 03切换到C ++ 11。

As I understand, some classes will benefit from the change by having an implicit default move constructor (and the move assignment operator that comes along). 据我所知,一些类将通过隐式默认移动构造函数(以及随之而来的移动赋值运算符)从更改中受益。 While I'm totally ok with that (I even think it is a nice thing) I'm a bit afraid of the effects that such implicit constructors might have on some non-copyable classes I have. 虽然我对此完全没问题(我甚至认为这是一件好事)但我有点害怕这些隐式构造函数可能对我所拥有的一些非可复制类产生的影响。

One example I have is a class that wraps an iconv_t handle from libiconv to leverage RAII. 我有一个例子是从libiconv包装iconv_t句柄以利用RAII的类。

More explicitely, the class is as follow: 更明确地说,课程如下:

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;
};

My concern is: if an instance of this class happened to be moved, this would result in a double call to iconv_close() . 我担心的是:如果碰巧移动了这个类的实例,这将导致对iconv_close()的双重调用。 As iconv_t is a "dumb" integral type, I don't expect the default implementation of iconv_wrapper(iconv_wrapper&&) to nullify the m_iconv member of the R-value. 由于iconv_t是一个“哑”整数类型,我不希望iconv_wrapper(iconv_wrapper&&)的默认实现使R值的m_iconv成员无效。 Even if it did, the destructor is not implemented to handle this properly. 即使它确实如此,也没有实现析构函数来正确处理它。

So my questions are: 所以我的问题是:

  • Are my concerns legitimate ? 我的担忧是否合法? Am I right that the default movable constructor/operator= will be incorrect in such a case ? 我是对的,在这种情况下,默认的可移动构造函数/运算符=是不正确的吗?
  • What changes can I make to port this code nicely to C++11 ? 我可以对C ++ 11很好地移植这段代码做些什么改变? (I was suggested std::unique_ptr but I couldn't make this work nicely, as it expects a pointer, not some opaque type) (我被建议使用std::unique_ptr但我无法很好地完成这项工作,因为它需要一个指针,而不是一些不透明的类型)

It won't be moved. 它不会被移动。 Because you have a user declared copy constructor, copy assignment operator and destructor, the move constructor and move assignment operator will not be generated. 因为您有一个用户声明的复制构造函数,复制赋值运算符和析构函数,所以不会生成移动构造函数和移动赋值运算符。 Actually, any one of those three declared would suppress automatic generation of the move constructor and move assignment operator. 实际上,这三个声明中的任何一个都会抑制自动生成移动构造函数和移动赋值运算符。

If you want to make it more C++11 friendly, you could add a move constructor and move assignment operator, as in (warning: never compiled or tested): 如果你想让它更友好,你可以添加一个移动构造函数和移动赋值运算符,如(警告:从未编译或测试):

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;
};

A reason you might want to do this is so you can store these objects (or other types which contain these objects) in a vector. 您可能希望这样做的原因是您可以将这些对象(或包含这些对象的其他类型)存储在向量中。

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

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