2016-09-18 7 views
0

は、おそらくこれが求められており、すでに答えが、私はのために検索するかわかりません。データメンバーが移動代入演算子が定義されている場合移動セマンティクス

は、非ポインタデータメンバーのセマンティクスを動かすのに使用することはできますか?

は、私はこのようなM::operator=(M&&)を定義するクラスMがあるとします。

template <class T> 
class M 
{ 
public: 
    M() 
    { 
     mem_M = new T; 
    } 

    M& operator=(M&& src) 
    { 
     if (this != &src) 
     { 
      mem_M = src.mem_M; 
      src.mem_M = nullptr; 
     } 
     return *this; 
    } 

private:  
    T* mem_M; 
}; 

今、明らかに私はTの移動代入演算子のない利用しない移動コンストラクタで、次のようにクラスC<T>を持つことができます。

template <class T> 
class C 
{ 
public: 
    C() 
    { 
     mem_C = new T; 
    } 
    C (C&& rhs) 
    { 
     mem_C = rhs.mem_C; 
     rhs.mem_C = nullptr; 
    } 

private: 
    T* mem_C; 
}; 

しかし、私は私が入居機能でC<T>::mem_Cに対処する方法を、ポインタが、普通のメンバーでないためにC<T>::mem_Cを何場合はどうでしょうか。私はもちろん、他の1つのインスタンスから提出されたmem_Cを移動する移動代入演算子T::operator=(T&&)を呼び出すことができますが、どのように私はきちんとC<T>::C(C&&)に渡さCのインスタンスをリセットするのですか?

これは、少なくとも私には間違っているになります。

template <class T> 
class C 
{ 
public: 
    C() 
    { 
     mem_C = T(); 
    } 
    C (C<T>&& rhs) 
    { 
     mem_C = std::move(rhs.mem_C); 
     rhs.mem_C = T();   // ?? like this? 
    } 

private: 
    T mem_C; 
}; 

ので、移動機能に非ポインタデータメンバーをリセットするには、標準に準拠しな方法は何ですか?含まれているタイプの

+0

ポインタは「普通のメンバー」のサブセットです。あなたは移動クラス型と非クラス型 –

+0

'mem_C = T()との違いについて尋ねているように見える;'削除する必要があり、オブジェクトは既に、これは単に時間とリソースを浪費ように構成されています。この場合 –

+0

は、あなたがとデフォルトムーブ代入演算子を使用する必要があり([ゼロのルールを参照してください(http://en.cppreference.com/w/cpp/language/rule_of_three))ことができ –

答えて

3

移動割り当て/コンストラクタは、それはそのタイプのあらゆる手段、「許容される」状態でオブジェクトを離れなければなりません。移動されるタイプの外側には、オブジェクトの状態を維持する責任はありません。

また、あなたはあなたの例であるとして、あなたがあなたの親の動きコンストラクタ、いない含まれているタイプの動き割り当て中に含まれる種類のコンストラクタが動きを呼んでいるようにしたい:

// move constructor calls move constructor of contained elements 
C (C<T>&& rhs) : mem_c(std::move(rhs.mem_c)) 
{ 
    // anything in here is using already-constructed data members 
} 

// move assignment calls move assignment of contained elements 
C & operator=(C<T>&& rhs) { 
    mem_c = std::move(rhs.mem_c); 
} 
関連する問題