2015-11-27 8 views
24

投稿者によって喚起されましたWhy does destructor disable generation of implicit move methods?、私は、デフォルト仮想デストラクタで同じことが当てはまるかどうか疑問に思っていました。デフォルトの仮想デストラクタは、コンパイラが生成した移動操作を防止しますか?

class WidgetBase // Base class of all widgets 
{ 
    public: 
     virtual ~WidgetBase() = default; 
     // ... 
}; 

クラスは、私は、基本クラスのポインタを操作する際のメモリリークと未定義の動作を避けるために、仮想デストラクタを定義する必要がウィジェット階層の基底クラスであることを意図しています。一方、コンパイラが自動的に移動操作を生成しないようにしたいとは思いません。

デフォルトの仮想デストラクタは、コンパイラ生成の移動操作を防止しますか?

答えて

21

はい、デストラクタを宣言すると、ムーブコンストラクタの暗黙宣言が無効になります。

N3337 [class.copy]/9:クラスXの定義は明示的に移動コンストラクタを宣言していない場合はデフォルト設定としてだけであれば

  • Xは、ユーザーが宣言したコピーコンストラクタを持っていない場合、1が暗黙のうちに 宣言されます、
  • Xは、
  • Xは、ユーザーが宣言した移動代入演算子を持っていない、ユーザーが宣言したコピー代入演算子を持っていない
  • Xにはユーザーが宣言したデストラクタがありません。
  • 移動コンストラクタは暗黙的に削除として定義されません。

デストラクタを宣言し、ユーザー宣言としてdefaultカウントとしてそれを定義します。あなたは移動コンストラクタを宣言し、defaultとしてそれを自分で定義する必要があります

:あなたもその1 defaultする必要がありますので、これは順番に、deleteとしてコピーコンストラクタを定義すること

WidgetBase(WidgetBase&&) = default; 

は注意:

WidgetBase(const WidgetBase&) = default; 

コピーのためのルールはと移動代入演算子は、同様にかなり似ているので、あなたがそれらをしたい場合は、defaultにそれらを持っています。