web-dev-qa-db-ja.com

「=デフォルト」デストラクタと空のデストラクタの違いは何ですか?

クラスのユーザーが自動変数として使用できないようにしたいので、次のようなコードを記述します。

_class A {
private:
  ~A() = default;
};

int main() {
  A a;
}
_

コードはコンパイルされないと思いますが、g ++はエラーなしでコンパイルします。

ただし、コードを次のように変更すると、次のようになります。

_class A {
private:
  ~A(){}
};

int main() {
  A a;
}
_

さて、g ++は、私の予想どおり、~A()がプライベートであるというエラーを出します。

「=デフォルト」デストラクタと空のデストラクタの違いは何ですか?

31
delphifirst

最初の例はコンパイルしないでください。これは、コンパイルするコンパイラのバグを表しています。このバグはgcc4.9以降で修正されています。

この場合、= defaultで定義されたデストラクタはtrivialです。これはstd::is_trivially_destructible<A>::valueで検出できます。

更新

C++ 11(およびC++ 14)は、user-declaredデストラクタがある場合(およびどちらのuser-も持っていない場合)宣言されたmovespecial member)の場合、コピーコンストラクタとコピー割り当て演算子の暗黙的な生成は引き続き発生しますが、その動作は非推奨になります。つまり、これに依存している場合、コンパイラは非推奨の警告を表示する場合があります(または表示しない場合があります)。

両方:

~A() = default;

そして:

~A() {};

user-declaredであるため、この点に関しては違いはありません。これらのフォームのいずれかを使用する場合(および移動メンバーを宣言しない場合)、非推奨の動作に依存しないように、コピーメンバーを明示的にデフォルト設定、明示的に削除、または明示的に提供する必要があります。

(デストラクタの宣言の有無にかかわらず)移動メンバーを宣言すると、コピーメンバーは暗黙的に削除されます。

25
Howard Hinnant