7

C ++ 0xでは、特定の関数をデフォルトとして指定できます。

struct A {
  A() = default;          // default ctor
  A(A const&) = default;  // copy ctor
  A(A&&) = default;       // move ctor
  A(Other);               // other ctor

  ~A() = default;         // dtor

  A& operator=(A const&) = default; // copy assignment
  A& operator=(A&&) = default;      // move assignment
};

これらの関数の実装は、コンパイラーがそれらを生成した場合と同じです。これは、ほとんどの状況で、独自の関数を宣言しない場合に通常発生します。

いずれかのctor(上記の他のいずれか)を宣言した場合、デフォルトのctorは生成されないため、デフォルトで「元に戻す」必要がある場合があります。

ただし、ベースまたはデータメンバーがそれらを除外しない限り、クラスには常にコピーアンドムーブctor⁠—⁠があり、それらが除外されている場合、デフォルトの実装は機能しません。クラスには常にdtorがあります。

コピーctor、移動ctor、またはデストラクタを明示的にデフォルト設定する必要があるのはなぜですか?とにかく、暗黙的に生成された実装は同じことをしませんか?

4

2 に答える 2

11

非公開へのアクセスを変更したり、どの翻訳ユニットがそれらを定義するかを制御したりするために、これを行う必要がある場合があります。

非公開

これらの関数は一般に公開されていますが、デフォルトの実装を希望する場合は、非公開にすることをお勧めします。

struct A {
protected:
  ~A();

private:
  A();
  A(A const&);
  A(A&&);
};

// according to N3092, §8.4.2/2, cannot be non-public and defaulted
// in the class definition
A::~A() = default;
A::A() = default;
A::A(A const&) = default;
A::A(A&&) = default;

このクラスは、デフォルトで構築、コピー、および移動できますが、Aのメソッドとその仲間によってのみ可能です。これは、構築がより厳密に制御される可能性があるファクトリに役立ちます。

保護されたデストラクタは、基本クラスのパブリック仮想/保護された非仮想ガイドラインの後半です。

ガイドライン#4:基本クラスのデストラクタは、パブリックで仮想、または保護されて非仮想である必要があります。

定義制御

さらに、デフォルトの関数を使用して、デフォルトの関数を定義する場所を制御できるため、安定したバイナリインターフェイスを維持できます。暗黙的に宣言されたバージョンのように、デフォルトはインラインを意味しません。(上記のコードでは、デフォルトの関数はヘッダーに含まれていないか、インライン指定子が追加されている必要があります。)

于 2010-09-27T14:57:30.180 に答える
2

機能的な目的に加えて、わかりやすくするためにも役立ちます。構造体がデフォルトで構築可能 (または何でも) であること、およびコンパイラが生成した動作を使用していることを明確にします。コードの自己文書化が進むほど、より良い結果が得られます。

于 2010-09-27T15:35:35.250 に答える