2017-04-15 6 views
1

アイテム17:特殊なメンバー関数の生成を理解する。"Effective Modern C++"におけるC++のデフォルトの移動操作

  1. 移動操作のみをクラス化欠け
    明示的に宣言移動操作、コピー操作、 またはデストラクタのために生成されます。今

  2. 、私は移動操作移動-構築
    または移動-割り当てるデータメンバまたは基本クラスを参照してください、そこ
    は動きが実際に行われることを保証するものではありません。
    実際には、移動可能(...)でないタイプ(...)
    は、コピー操作によって「移動」されるため、「メンバーシップムーブ」は、実際にはメンバーごとに
    の移動要求に似ています。

ただし、自分の環境では確認できません。

// compiled 
#include <iostream> 
using namespace std; 
class Base { 
public: 
    ~Base() {} 
}; 
int main() { 
    Base a, c; 
    Base b(move(a)); 
    c = move(b); 
    // explicitly destructor does not disable 
    // default move constuctor and move assignment operator 
    return 0; 
} 

class Base { 
public: 
    Base() {} 
    Base(Base& b) {} 
    ~Base() {} 
}; 
class Num { 
private: 
    Base b; 
}; 
int main() { 
    Num a, c; 
    c = move(a); // passed 
    Num b(move(c)); // error 
    // explicitly Base::Base(Base& b) disable default move 
    // move conctructor. 
    // Num's default move constructor can not find any move 
    // constructor for member object Base b, which lead to an 
    // error. Num's default move constructor does not "moved" 
    // Base b via their copy operations which is declared. 
    return 0; 
} 

最初の主張は異なる環境から異なるかもしれないが、もう一つは、ほとんど間違っています。
私はそれについて非常に混乱しています。 私を助けてください。

答えて

0
class Base { 
public: 
    ~Base() {} 
}; 

Baseは、ユーザーが宣言したデストラクタを持っているので、移動のコンストラクタを持っているか、全く代入演算子を移動しません。行

Base b(move(a)); 
c = move(b); 

実際にコピーコンストラクタとコピー代入演算子をそれぞれ呼び出します。

class Base { 
public: 
    Base() {} 
    Base(Base& b) {} 
    ~Base() {} 
}; 
class Num { 
private: 
    Base b; 
}; 

また、Baseには、移動コンストラクタがまったくありません。ただし、Numには暗黙的に宣言された移動コンストラクタがあります。Num自体は特別なメンバ関数を宣言していないためです。削除されたように、デフォルトの定義が悪い形成されるためしかし、それは暗黙的に、定義されます。bの「移動」はコピーコンストラクタを使用する試みを行いますが、それができないことを

Num::Num(Num&& n) : b(std::move(n.b)) {} 
// Cannot convert rvalue of type `Base` to `Base&` 
// for the copy constructor to be called. 

注意。

+0

説明をよろしくお願いします。私は今はっきりしています! – gfxcc

関連する問題