logo

C++ コピー コンストラクター

コピーコンストラクターは、 過負荷 別のオブジェクトからオブジェクトを宣言して初期化するために使用されるコンストラクター。

コピー コンストラクターには 2 つのタイプがあります。

    デフォルトのコピーコンストラクター:コンパイラはデフォルトのコピー コンストラクターを定義します。ユーザーがコピー コンストラクターを定義しない場合、コンパイラーはそのコンストラクターを提供します。ユーザー定義のコンストラクター:プログラマはユーザー定義のコンストラクターを定義します。
C++ コピー コンストラクター

ユーザー定義のコピー コンストラクターの構文:

 Class_name(const class_name &old_object); 

次の状況を考えてみましょう。

キャッチアンドトライJava
 class A { A(A &x) // copy constructor. { // copyconstructor. } } 

上記の場合、 コピー コンストラクターは次の方法で呼び出すことができます。

C++ コピー コンストラクター

コピー コンストラクターの簡単な例を見てみましょう。

// コピーコンストラクターのプログラム。

 #include using namespace std; class A { public: int x; A(int a) // parameterized constructor. { x=a; } A(A &amp;i) // copy constructor { x = i.x; } }; int main() { A a1(20); // Calling the parameterized constructor. A a2(a1); // Calling the copy constructor. cout&lt; <a2.x; return 0; } < pre> <p> <strong>Output:</strong> </p> <pre> 20 </pre> <h2>When Copy Constructor is called</h2> <p>Copy Constructor is called in the following scenarios:</p> <ul> <li>When we initialize the object with another existing object of the same class type. For example, Student s1 = s2, where Student is the class.</li> <li>When the object of the same class type is passed by value as an argument.</li> <li>When the function returns the object of the same class type by value.</li> </ul> <h2>Two types of copies are produced by the constructor:</h2> <ul> <li>Shallow copy</li> <li>Deep copy</li> </ul> <h2>Shallow Copy</h2> <ul> <li>The default copy constructor can only produce the shallow copy.</li> <li>A Shallow copy is defined as the process of creating the copy of an object by copying data of all the member variables as it is.</li> </ul> <p>Let&apos;s understand this through a simple example:</p> <pre> #include using namespace std; class Demo { int a; int b; int *p; public: Demo() { p=new int; } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << 'value of b is : ' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-3.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has not defined any constructor, therefore, the statement <strong>Demo d2 = d1;</strong> calls the default constructor defined by the compiler. The default constructor creates the exact copy or shallow copy of the existing object. Thus, the pointer p of both the objects point to the same memory location. Therefore, when the memory of a field is freed, the memory of another field is also automatically freed as both the fields point to the same memory location. This problem is solved by the <strong>user-defined constructor</strong> that creates the <strong>Deep copy</strong> .</p> <h2>Deep copy</h2> <p>Deep copy dynamically allocates the memory for the copy and then copies the actual value, both the source and copy have distinct memory locations. In this way, both the source and copy are distinct and will not share the same memory location. Deep copy requires us to write the user-defined constructor.</p> <p>Let&apos;s understand this through a simple example.</p> <pre> #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << 'value of b is : ' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<></pre></a2.x;>

コピーコンストラクターが呼び出されたとき

コピー コンストラクターは、次のシナリオで呼び出されます。

  • 同じクラスタイプの別の既存のオブジェクトを使用してオブジェクトを初期化するとき。たとえば、Student s1 = s2 (Student はクラス) です。
  • 同じクラス型のオブジェクトが引数として値渡しされる場合。
  • 関数が同じクラス型のオブジェクトを値で返す場合。

コンストラクターによって 2 種類のコピーが生成されます。

  • 浅いコピー
  • ディープコピー

浅いコピー

  • デフォルトのコピー コンストラクターは浅いコピーのみを作成できます。
  • 浅いコピーとは、すべてのメンバ変数のデータをそのままコピーしてオブジェクトのコピーを作成する処理と定義されます。

簡単な例を通してこれを理解してみましょう。

 #include using namespace std; class Demo { int a; int b; int *p; public: Demo() { p=new int; } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-3.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has not defined any constructor, therefore, the statement <strong>Demo d2 = d1;</strong> calls the default constructor defined by the compiler. The default constructor creates the exact copy or shallow copy of the existing object. Thus, the pointer p of both the objects point to the same memory location. Therefore, when the memory of a field is freed, the memory of another field is also automatically freed as both the fields point to the same memory location. This problem is solved by the <strong>user-defined constructor</strong> that creates the <strong>Deep copy</strong> .</p> <h2>Deep copy</h2> <p>Deep copy dynamically allocates the memory for the copy and then copies the actual value, both the source and copy have distinct memory locations. In this way, both the source and copy are distinct and will not share the same memory location. Deep copy requires us to write the user-defined constructor.</p> <p>Let&apos;s understand this through a simple example.</p> <pre> #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<></pre></a<<>
C++ コピー コンストラクター

上記の場合、プログラマはコンストラクタを定義していないため、ステートメントは次のようになります。 デモ d2 = d1; コンパイラによって定義されたデフォルトのコンストラクターを呼び出します。デフォルトのコンストラクターは、既存のオブジェクトの正確なコピーまたは浅いコピーを作成します。したがって、両方のオブジェクトのポインタ p は同じメモリ位置を指します。したがって、フィールドのメモリが解放されると、両方のフィールドが同じメモリ位置を指しているため、別のフィールドのメモリも自動的に解放されます。この問題は次の方法で解決されます。 ユーザー定義コンストラクター それは ディープコピー

配列スライスJava

ディープコピー

ディープ コピーでは、コピーにメモリを動的に割り当ててから実際の値をコピーします。ソースとコピーの両方に個別のメモリ位置があります。このように、ソースとコピーは両方とも別個のものであり、同じメモリ位置を共有しません。ディープコピーでは、ユーザー定義のコンストラクターを作成する必要があります。

簡単な例を通してこれを理解しましょう。

 #include using namespace std; class Demo { public: int a; int b; int *p; Demo() { p=new int; } Demo(Demo &amp;d) { a = d.a; b = d.b; p = new int; *p = *(d.p); } void setdata(int x,int y,int z) { a=x; b=y; *p=z; } void showdata() { std::cout &lt;&lt; &apos;value of a is : &apos; &lt; <a<< std::endl; std::cout << \'value of b is : \' < <b<< *p <<*p<< } }; int main() { demo d1; d1.setdata(4,5,7); d2="d1;" d2.showdata(); return 0; pre> <p> <strong>Output:</strong> </p> <pre> value of a is : 4 value of b is : 5 value of *p is : 7 </pre> <img src="//techcodeview.com/img/c-tutorial/75/c-copy-constructor-4.webp" alt="C++ Copy Constructor"> <p>In the above case, a programmer has defined its own constructor, therefore the statement <strong>Demo d2 = d1;</strong> calls the copy constructor defined by the user. It creates the exact copy of the value types data and the object pointed by the pointer p. Deep copy does not create the copy of a reference type variable.</p> <h2>Differences b/w Copy constructor and Assignment operator(=)</h2> <table class="table"> <tr> <th>Copy Constructor</th> <th>Assignment Operator</th> </tr> <tr> <td>It is an overloaded constructor.</td> <td>It is a bitwise operator.</td> </tr> <tr> <td>It initializes the new object with the existing object.</td> <td>It assigns the value of one object to another object.</td> </tr> <tr> <td>Syntax of copy constructor: <br> Class_name(const class_name &amp;object_name) <br> { <br> // body of the constructor. <br> }</td> <td>Syntax of Assignment operator: <br> Class_name a,b; <br> b = a;</td> </tr> <tr> <td><ul> <li>The <strong>copy constructor</strong> is invoked when the new object is initialized with the existing object.</li> <li>The object is passed as an argument to the function.</li> <li>It returns the object.</li> </ul></td> <td>The <strong>assignment operator</strong> is invoked when we assign the existing object to a new object.</td> </tr> <tr> <td>Both the existing object and new object shares the different memory locations.</td> <td>Both the existing object and new object shares the same memory location.</td> </tr> <tr> <td>If a programmer does not define the copy constructor, the compiler will automatically generate the implicit default copy constructor. </td> <td>If we do not overload the &apos;=&apos; operator, the bitwise copy will occur.</td> </tr> </table> <hr></a<<>
C++ コピー コンストラクター

上記の場合、プログラマは独自のコンストラクタを定義しているため、ステートメントは次のようになります。 デモ d2 = d1; ユーザーが定義したコピー コンストラクターを呼び出します。値型のデータとポインタ p が指すオブジェクトの正確なコピーを作成します。ディープ コピーでは、参照型変数のコピーは作成されません。

コピーコンストラクターと代入演算子(=)の違い

コピーコンストラクター 代入演算子
オーバーロードされたコンストラクターです。 ビット単位の演算子です。
新しいオブジェクトを既存のオブジェクトで初期化します。 あるオブジェクトの値を別のオブジェクトに割り当てます。
コピーコンストラクターの構文:
クラス名(const クラス名 &オブジェクト名)
{
// コンストラクターの本体。
}
代入演算子の構文:
クラス名 a、b;
b = a;
  • コピーコンストラクター 新しいオブジェクトが既存のオブジェクトで初期化されるときに呼び出されます。
  • オブジェクトは引数として関数に渡されます。
  • オブジェクトを返します。
代入演算子 既存のオブジェクトを新しいオブジェクトに割り当てるときに呼び出されます。
既存のオブジェクトと新しいオブジェクトは両方とも、異なるメモリ位置を共有します。 既存のオブジェクトと新しいオブジェクトは両方とも同じメモリ位置を共有します。
プログラマがコピー コンストラクターを定義しない場合、コンパイラーは暗黙的なデフォルトのコピー コンストラクターを自動的に生成します。 「=」演算子をオーバーロードしない場合、ビットごとのコピーが行われます。