[C++] デフォルトのコンストラクタとデストラクタの "= default"と "{}"の違いは?


Answers

彼らはどちらも自明ではありません。

それらは両方ともベースとメンバーのnoexcept仕様に応じて同じnoexcept仕様を持っています。

私が今検出している唯一の違いは、 Widgetにアクセスできないまたは削除されたデストラクタを持つベースまたはメンバーが含まれている場合です:

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

class Widget {
    A a_;
public:
#if 1
   virtual ~Widget() = default;
#else
   virtual ~Widget() {}
#endif
};

その後、 =default解法はコンパイルされますが、 Widgetは破壊的な型にはなりません。 つまり、 Widgetを破壊しようとすると、コンパイル時にエラーが発生します。 しかし、あなたがしなければ、あなたは働くプログラムを持っています。

Otoh、あなたがユーザー提供のデストラクタを提供すると、 Widgetを破棄するかどうかに関係なく、コンパイルされません。

test.cpp:8:7: error: field of type 'A' has private destructor
    A a_;
      ^
test.cpp:4:5: note: declared private here
    ~A();
    ^
1 error generated.
Question

私はもともとこれをデストラクタについての質問として投稿しましたが、今はデフォルトのコンストラクタを考慮しています。 ここに元の質問があります:

私のクラスに仮想的なデストラクタを与えたいが、それ以外の場合はコンパイラが生成するものと同じであるので、私は=defaultを使うことができる:

class Widget {
public:
   virtual ~Widget() = default;
};

しかし、私は空の定義を使用して少ないタイピングで同じ効果を得ることができるようです:

class Widget {
public:
   virtual ~Widget() {}
};

これらの2つの定義が異なって振る舞う方法はありますか?

この質問に対して投稿された回答に基づいて、デフォルトのコンストラクタの状況は類似しているようです。 デストラクタの " =default "と " {} "の意味にはほとんど違いがないので、デフォルトのコンストラクタのこれらのオプションの意味にはほとんど同様の意味がありますか? つまり、そのタイプのオブジェクトが作成され、破棄されるタイプを作成したいと仮定すると、なぜ私は言いたいのですか

Widget() = default;

の代わりに

Widget() {}

元の投稿が一部のSOルールに違反しているため、この質問を延長するとお詫び申し上げます。 デフォルトのコンストラクタについてはほとんど同じ質問を投稿すると、あまり望ましくないオプションとして私を襲った。




Links