The copy constructor is a mechanism to prevent data loss. For example, if the object being passed contains pointers to dyn. allocated memory. In my case it does not work.

#include "stdafx.h" #include <iostream> using namespace std; class myclass { public: int *var; myclass(int i) { cout << "Obuchnuy konstructor.\n"; var = new int; *var = i; } myclass(const myclass &obj) { cout << "Konstructor kopii.\n"; var = new int; *var = *obj.var; } ~myclass() { cout << "Destructor.\n"; delete var; } }; myclass f() { myclass ob(5); cout << *ob.var << endl; return ob; } int main() { myclass a(10); cout << *a.var << endl; a = f(); cout << *a.var << endl; return 0; } 

"Garbage" is displayed:

 Obuchnuy konstructor. 10 Obuchnuy konstructor. 5 Konstructor kopii. Destructor. Destructor. -17891602 Destructor. 

Why bother to use it at all if dyn. was the memory cleared by the delete operator just as it would have been cleared without a copy constructor? Only without it, "garbage" will appear when calling the destructor of the object myclass :: ob , and with it when calling the destructor of a temporary object.

  • In C ++ * obj.var, it is customary to write as obj-> var - German Borisov

1 answer 1

The problem is that you forgot to redefine the assignment operator. And it is explicitly called in your code ( a = f(); ).

In your case, the default assignment operator is used, which simply copies all fields, including the field with the pointer. Thus, you again get two objects with a pointer to the same data, and when one of them dies, it also “kills” other people's data.

Apparently, you are lucky and you use the debug version of the program and a friendly compiler, in which the data to be deleted changes the value. In the ordinary case, the data could not change outwardly, and you would find an error much later.

Pay attention to the rules of the "big two", "big three" (and in modern versions of the language of the big five):

  1. If you need a copy constructor or an assignment operator in a class, then you need both . (Most likely, you will need them if you have pointer fields in your class.)
  2. If your class does not prohibit inheritance, then in the list of item 1 you need to add a virtual destructor: if you need one of the three, then you need all three.

(Here is the detailed answer about the five rule for new versions of the language with move semantics. If you are not using move semantics, the three rule is enough.)