copy/move assignment

3371 ワード

copy assignment
object 1とobject 2があります
object 2をobject 1に割り当てる場合
object 2の内容はすべてobject 1にコピーされます.
Cat & operator=(const Cat& other) {
	mName = other.mName;
    mAge = other.mAge;
    cout << "copy assignment << endl; 
    return *this
}
copy付与のreturnタイプはreferenceです.
したがって、このオブジェクトのアドレスが示す内容を返すとよい(return*this)
int main() {
	Cat kitty{"kitty", 1};
    Cat nabi{"nabi", 2};
    kitty = nabi;
    kitty.print();
}
出力するとnabi objectのすべての情報がkittyにコピーされます.
出力nabi 2.
オブジェクトが2つある場合object 2がR値
object 2の内容はコピーではなく移動
Cat & operator=(const Cat&& other) {
	mName = std::move(other.mName);
    mAge = other.mAge;
    cout << "move assignment << endl; 
    return *this
}
stringオブジェクトとしてのその他.mNameは、R値に変換して所有権を取り戻すことができます.
intタイプのmAgeをコピーしました.
呼び出しmove assignment
int main() {
	Cat kitty{"kitty", 1};
    Cat nabi{"nabi", 2};
    kitty = std::move(nabi);
    kitty.print();
    nabi.print();
}
kitty = std::move(nabi);使用しました

出力後,kitty objectがstringの所有権に奪われ,nabiなしで2万個出力されることがわかる.
self assignment
int main() {
	Cat kitty{"kitty", 1};
    Cat nabi{"nabi", 2};
    
    kitty = kitty;
    kitty = std::move(kitty);
}
この状態で構築すれば問題ありません
ただし、char*mptrのようにchar pointerを使用してリソースを管理する場合は、
思いがけないことが起こる
それを防ぐために、2つが同じオブジェクトであれば、自分を返すコードを加えます.
Cat & operator = (Cat && other) {
  if (&other == this) {
      return * this;
  }
  ...
  ...
}
kitty = nabi;//copy assignment
kitty = std::move(nabi);//move assignment
発生した時の画面から見ると.

copy assignmentはkittyの内容をnabiの内容にコピーします.

move assignmentではnabiがkittyを指す所有権の変更を指すことがわかります.
destructor、move assignment、moveコンストラクション関数は例外を放出しないため、noexceptionを追加することが重要です.

前述したようにchar*mptrのようにポインタを使用してリソースを管理しない場合は、
Cat()、~Cat()、Cat&otherなどを直接作成する必要はありません.
int main() {
	Cat kitty{"kitty", 1};
    Cat nabi{"nabi", 2};
    
    kitty = kitty;
    kitty = std::move(kitty);
}
ポインタを使用しない場合は、copy、moveコンストラクション関数を定義せずに構築します.
コンパイラは自分で作るので大丈夫です
したがって,生産性の高いC++を開発するには,ポインタを用いてリソースを管理することは避けたほうがよい.
constructor、copy constructor、copyの割り当てを阻止する方法は、次のとおりです.
Cat() = delete;
Cat(const Cat& other) = delete;
Cat& operator = (const Cat& other) = delete;
このように=deleteでいいです.
C+11の前に、

このようにprivateに置くと、=deleteを貼り付ける動作と同じです.
staticメソッドのみのクラスではobjectを作成する必要はありません.
このときCat()=delete;構造関数自体を阻止するために利用するのも良い方法です.
単一のパターンでは、1つしかない必要があるため、copy構造関数、copy付与自体の存在を阻止することが望ましい.