logo

Konstruktor kopiujący C++

Konstruktor kopiujący to przeciążony konstruktor używany do deklarowania i inicjowania obiektu z innego obiektu.

Konstruktor kopiujący jest dwojakiego rodzaju:

    Domyślny konstruktor kopiujący:Kompilator definiuje domyślny konstruktor kopiujący. Jeśli użytkownik nie zdefiniuje żadnego konstruktora kopiującego, kompilator dostarcza jego konstruktor.Konstruktor zdefiniowany przez użytkownika:Programista definiuje konstruktor zdefiniowany przez użytkownika.
Konstruktor kopiujący C++

Składnia konstruktora kopiującego zdefiniowanego przez użytkownika:

 Class_name(const class_name &old_object); 

Rozważ następującą sytuację:

przykład mapy Java
 class A { A(A &x) // copy constructor. { // copyconstructor. } } 

W powyższym przypadku Konstruktor kopiujący można wywołać w następujący sposób:

Konstruktor kopiujący C++

Zobaczmy prosty przykład konstruktora kopiującego.

// program konstruktora kopiującego.

 #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;>

Po wywołaniu konstruktora kopiującego

Konstruktor kopiujący jest wywoływany w następujących scenariuszach:

  • Kiedy inicjujemy obiekt innym istniejącym obiektem tego samego typu klasy. Na przykład Student s1 = s2, gdzie Student jest klasą.
  • Gdy obiekt tego samego typu klasy jest przekazywany przez wartość jako argument.
  • Gdy funkcja zwraca obiekt tego samego typu klasy według wartości.

Konstruktor tworzy dwa rodzaje kopii:

  • Płytka kopia
  • Głęboki egzemplarz

Płytka kopia

  • Domyślny konstruktor kopiujący może wygenerować tylko płytką kopię.
  • Płytką kopię definiuje się jako proces tworzenia kopii obiektu poprzez kopiowanie danych wszystkich zmiennych składowych w niezmienionej postaci.

Rozumiemy to na prostym przykładzie:

gimp usuń znak wodny
 #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<<>
Konstruktor kopiujący C++

W powyższym przypadku programista nie zdefiniował żadnego konstruktora, dlatego też instrukcja Demo d2 = d1; wywołuje domyślny konstruktor zdefiniowany przez kompilator. Konstruktor domyślny tworzy dokładną kopię lub płytką kopię istniejącego obiektu. Zatem wskaźnik p obu obiektów wskazuje to samo miejsce w pamięci. Dlatego też, gdy pamięć jednego pola zostanie zwolniona, pamięć innego pola również zostanie automatycznie zwolniona, ponieważ oba pola wskazują na tę samą lokalizację w pamięci. Problem ten rozwiązuje tzw konstruktor zdefiniowany przez użytkownika która tworzy Głęboki egzemplarz .

Głęboki egzemplarz

Głęboka kopia dynamicznie przydziela pamięć dla kopii, a następnie kopiuje rzeczywistą wartość. Zarówno źródło, jak i kopia mają różne lokalizacje pamięci. W ten sposób zarówno źródło, jak i kopia są odrębne i nie będą dzielić tej samej lokalizacji w pamięci. Głębokie kopiowanie wymaga od nas napisania konstruktora zdefiniowanego przez użytkownika.

Rozumiemy to na prostym przykładzie.

 #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<<>
Konstruktor kopiujący C++

W powyższym przypadku programista zdefiniował własny konstruktor, a więc instrukcję Demo d2 = d1; wywołuje konstruktor kopiujący zdefiniowany przez użytkownika. Tworzy dokładną kopię danych typów wartościowych i obiektu wskazywanego przez wskaźnik p. Głęboka kopia nie tworzy kopii zmiennej typu referencyjnego.

Różnice b/w Konstruktor kopiujący i operator przypisania (=)

Kopiuj konstruktor Operator przypisania
Jest to przeciążony konstruktor. Jest to operator bitowy.
Inicjuje nowy obiekt za pomocą istniejącego obiektu. Przypisuje wartość jednego obiektu innemu obiektowi.
Składnia konstruktora kopiującego:
Nazwa_klasy(stała nazwa_klasy &nazwa_obiektu)
{
//Ciało konstruktora.
}
Składnia operatora przypisania:
Nazwa_klasy a, b;
b = a;
  • The konstruktor kopiujący jest wywoływany, gdy nowy obiekt jest inicjowany przy użyciu istniejącego obiektu.
  • Obiekt przekazywany jest jako argument funkcji.
  • Zwraca obiekt.
The operator przypisania jest wywoływana, gdy przypiszemy istniejący obiekt do nowego obiektu.
Zarówno istniejący obiekt, jak i nowy obiekt dzielą różne lokalizacje pamięci. Zarówno istniejący obiekt, jak i nowy obiekt mają tę samą lokalizację w pamięci.
Jeśli programista nie zdefiniuje konstruktora kopiującego, kompilator automatycznie wygeneruje domyślny domyślny konstruktor kopiujący. Jeśli nie przeciążymy operatora „=”, nastąpi kopiowanie bitowe.