rule-of-three - c++ コーディング規約 ipa - 三つの法則」とは?

C++ 意味 / c++ / copy-constructor / assignment-operator / c++-faq

  • オブジェクトのコピーとはどういう意味ですか?
  • 何でコピーコンストラクタコピー代入演算子は
  • 自分で宣言する必要があるのはどんな時ですか?
  • 自分のオブジェクトがコピーされないようにするにはどうしたらいいですか?

Rann Lifshitz



Answer #1

ここはオブジェクト指向の言語なので(少なくともそう仮定している)、メモリの一部を割り当てたとします。OO言語なので、割り当てたメモリの塊はたいていプリミティブ変数(ints,chars,bytes)か、自分で定義した型やプリミティブでできたクラスなので、簡単に参照することができます。つまり、次のようなCarのクラスがあるとします。

class Car //A very simple class just to demonstrate what these definitions mean.
//これは擬似コードC ++ / Javaishであり、文字列を割り当てる必要はないと思います。
{
private String sPrintColor;
private String sModel;
private String sMake;

public changePaint(String newColor)
{
   this.sPrintColor = newColor;
}

public Car(String model, String make, String color) //コンストラクタ
{
   this.sPrintColor = color;
   this.sModel = model;
   this.sMake = make;
}

public ~Car() //デストラクタ
{
//カスタムタイプを作成しなかったため、コードを追加していません。
//オブジェクトがスコープ外になると/プログラムがガベージを収集する/など。この男は+他のすべての関連するデストラクタと呼ばれます。
//文字列以外は使用しなかったため、追加で処理するものはありません。
// 3つの文字列は文字列のデストラクタによって処理され、自動的に呼び出されると想定されています。そうでない場合は、ここで行う必要があります。
}

public Car(const Car &other) //コンストラクタをコピーします
{
   this.sPrintColor = other.sPrintColor;
   this.sModel = other.sModel;
   this.sMake = other.sMake;
}
public Car &operator =(const Car &other) //代入演算子
{
   if(this != &other)
   {
      this.sPrintColor = other.sPrintColor;
      this.sModel = other.sModel;
      this.sMake = other.sMake;
   }
   return *this;
}

}

ディープコピーとは、オブジェクトを宣言した後に、そのオブジェクトの完全に別のコピーを作成することです。

Car car1 = new Car("mustang", "ford", "red");
Car car2 = car1; //コピーコンストラクタを呼び出す
car2.changePaint("green");
// car2は緑になりましたが、car1はまだ赤です。

さて、ちょっと変わったことをしてみましょう。例えば、car2のプログラムが間違っているか、わざとcar1が作った実際のメモリを共有するようになっているとします。(このようなことをするのは通常は間違いであり、授業ではたいてい毛布を被って議論されます)。あなたがcar2について尋ねるときはいつでも、実際にはcar1のメモリ空間へのポインタを解決していると仮定してください...それは多かれ少なかれ浅いコピーと同じです。

//浅いコピーの例
//操作用に作成されたコンストラクターがない場合、オブジェクトを浅くコピーするのが標準的な動作であるため、C ++を使用していると想定します。
//ここで、上記のような割り当てまたはコピー操作のコードがないと仮定します...これらがなくなったため、C ++はデフォルトを使用します。

 Car car1 = new Car("ford", "mustang", "red"); 
 Car car2 = car1; 
 car2.changePaint("green");// car1も緑色になりました
 delete car2;/ *実際にはあなたの車でもある私の車を取り除きます... car2が存在する場所のアドレスを解決し、メモリを削除するようにC ++に指示しました...これはあなたの車に関連付けられたメモリでもあります。* /
 car1.changePaint("red");/ *この領域がプログラムに割り当てられなくなったため、プログラムがクラッシュする可能性があります。* /