5

クラス X がクラス Y から派生し、クラス Y が次のいずれかを持つ場合:

  • ユーザー宣言のコピー コンストラクター
  • ユーザー宣言のコピー代入演算子、
  • ユーザー宣言のデストラクタ
  • ユーザー宣言のムーブ コンストラクター
  • ユーザー宣言の移動代入演算子、

上記のいずれも宣言しない場合、移動コンストラクターと移動代入演算子は、クラス X に対して暗黙的にデフォルト設定されますか?

例えば

struct Y
{
     virtual ~Y() {}

     // .... stuff

};

struct X : public Y
{
   // ... stuff but no destructor, 
   //               no copy/move assignment operator 
   //               no copy/move constructor

   // will X have a default move constructor / assignment operator?
};

私は現在 gcc を使用していますが、主に正しい動作がどうあるべきか (特定のコンパイラが標準に準拠しているかどうかではなく) に関心があります。

4

2 に答える 2

3

派生クラスに関する限り、属性または基本クラスにユーザー定義または暗黙の特殊関数があるという事実は重要ではありません。重要なのは彼らの存在です。

int対応する C++11 コンパイラは、動的に割り当てられたバッファーを持つクラスのみが実際に恩恵を受ける (コピーするだけです)。

したがって、クラスに astd::stringまたは a std::unique_ptr(たとえば) が埋め込まれている場合、その移動コンストラクターは埋め込みstringまたはunique_ptr移動コンストラクターを呼び出し、効率的になります...無料です。

したがって、コンパイル モードを変更するだけで、パフォーマンスがわずかに向上します。

于 2012-05-22T10:51:49.960 に答える
2

はい、§12.8.9では次のようになっています。

クラスXの定義でmoveコンストラクターが明示的に宣言されていない場合、moveコンストラクターは、次の場合にのみデフォルトとして暗黙的に宣言されます。

  • Xには、ユーザーが宣言したコピーコンストラクターがありません。
  • Xには、ユーザーが宣言したコピー代入演算子がありません。
  • Xには、ユーザーが宣言したムーブ代入演算子がありません。
  • Xには、ユーザーが宣言したデストラクタがなく、
  • 移動コンストラクターは、削除済みとして暗黙的に定義されません。

および§12.8.10

クラスXに対して暗黙的に宣言された移動コンストラクターは、次の形式になります。

X::X(X&&)

同様に、12.8.20のムーブ代入演算子の場合:

クラスXの定義でムーブ代入演算子が明示的に宣言されていない場合、ムーブ代入演算子は、次の場合にのみデフォルトとして暗黙的に宣言されます。

  • Xには、ユーザーが宣言したコピーコンストラクターがありません。
  • Xには、ユーザーが宣言した移動コンストラクターがありません。
  • Xには、ユーザーが宣言したコピー代入演算子がありません。
  • Xには、ユーザーが宣言したデストラクタがなく、
  • ムーブ代入演算子は、暗黙的に削除済みとして定義されません。

基本クラスは直接それには入りません。

于 2012-05-22T10:52:46.470 に答える