C++ディープコピーとライトコピー&リロード付与演算子

2194 ワード

プログラムがオブジェクトのコピーを生成すると、コンパイラは自動的にコピー(コピー)コンストラクタを呼び出します.
C++クラスのメンバ変数にポインタ変数が存在する場合,深いコピーと浅いコピーの問題がある.C++コンパイラがデフォルトで提供するコピーコンストラクタまたはオブジェクトの割り当て操作を使用すると、浅いコピーが発生し、コンストラクタ中にエラーが発生します.
下記のコードでは、1つのオブジェクトを作成するときにコンストラクタ割り当てメモリを呼び出して初期化するが、①コピーコンストラクタを手動で作成していないときに、1つのオブジェクトで新しいオブジェクトを初期化すると、C++コンパイラは浅いコピーを完了し、単純に変数を割り当てるだけで、ポインタ変数を単純に割り当てるのは、新しいオブジェクトのポインタ変数にアドレスを割り当てるだけで、2つのオブジェクトのポインタ変数は同じメモリ空間を指します.このように,構造関数の構造順序に基づいて,新しいオブジェクトが構造化されるとメモリが解放され,オブジェクトが構造化されるとメモリアクセスエラーが発生する.②等号演算子リロード関数を手動で作成しない場合は、上記①と同じ原理になります.
class Name
{
public:
	Name(const char *str)
	{
		len = strlen(str);
		name = new char[len + 1];
		*(name + len) = '\0';
		memcpy(name, str, len);
	}

	~Name()
	{
		if (name != NULL)
		{
			delete[]name;
			name = NULL;
                        len = 0;
               }
	}
	void Print()
	{
		cout << "The name is :" << name << endl;
	}
private:
	char *name;
	int len;
};

int main()
{
	Name n1("Micheal");
	Name n2 = n1;//  n1          。        
        Name n3;
      n3 = n1;//      ,  “=”    
       n2.Print();
	n1.Print();
        n3.Print();
 system("pause");return 0;}
     Name                             。  Name                      
   
	//      
        Name(const Name& n)
	{
		len = strlen(n.name);
		name = new char[len + 1];
		memcpy(name, n.name, len);
		*(name + len) = '\0';
	}

	
//         
        void operator=(const Name& n)
	{
               if (name != NULL)
          {
            delete[]name;
            name = NULL;
            len = 0;
           }
               len = strlen(n.name);
		name = new char[len + 1];
		memcpy(name, n.name, len);
		*(name + len) = '\0';
	}

まとめ:
コピーコンストラクタは、プログラムに のような がある に び されます.
① のクラスオブジェクトで しいオブジェクトを に する
② が でオブジェクトを したり、オブジェクトを したりする
③コンパイラが オブジェクトを する 、3つのオブジェクトを すると、コンパイラが オブジェクトを する があります.
にポインタ などのアドレス がある は、レプリケーションコンストラクタと オペレータリロード を で する があります.そうしないと、コンパイラがコンパイラ が したコピーコンストラクタまたは オペレータリロード を び すと、プロファイル にエラーが しやすくなります.