簡體   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