For a class, we refer to copy constructor, copy-assignment operator, move constructor, move-assignment operator, destructor collectively as copy Control
Today we first talk about the copy constructor, copy-assignment operator destructor these three.
Copy constructor
copy constructor: A constructor If his first argument is a reference to the class, and the other parameters have default values (default values), this is a copy constructor.
1, the first argument must be a reference type, because when we pass an object as a parameter to the non-reference variable of a method, the copy constructor method is called automatically, if the copy constructor own argument is a non-reference type, This method will cause an infinite recursive call, and your program will be boomshakalaka~~.
2, generally we will set the first parameter to const, because it will not be modified in general, unless you have another plan.
3, because copy constructor is called by default in many cases, the copy constructor is not generally set to explicit if the following is the case.
1 std::string s; 2 std::string// implicitly called copy constructor3 std::string s2 = std:: string (S1); // the copy constructor is explicitly called
1 class foo{2public:3 Foo (const foo&); 4 // ... 5 };
When the copy constructor call occurs
To figure this out, we need to figure out another set of concepts: direct initialization and copy initialization.
Direct initialization: Requires the compiler to select the method to invoke by a generic method match (function matching).
Copy initialization: Requires the compiler to copy the right operand to the left operand and, if necessary, a type conversion, which invokes copy constructor or move constructor (not described in this article).
1STD::stringS1 ("Balabala");//Direct Initialization2STD::stringS2 (Ten,'a');//Direct Initialization3STD::strings3 = S2;//Copy Initialization4STD::stringS4 = std::string(S3);//Copy Initialization5STD::stringS5 ="Const char* converts to string";//Copy Initialization
Copy initialization occurs as follows:
1, when using = to initialize the defined variable.
2, when an object is passed as a parameter to a non-reference variable of a method.
3, when the method returns an object of a non-reference type. (A temporary object is generated first when returned)
4, when initializing an array or aggregation class (aggregate Class) member with a curly brace list.
As a result of the compiler's misunderstanding:
Now the compiler sometimes automatically bypasses the copy constructor that the compiler will put the following sentence
Std::book book = "9-9-9-9"; // Suppose that book is a custom class
Switch to the following.
Std::book Book ("9-9-9-9");
Note that the above two sentences are completely different in execution, and the first sentence will first call the book (const char*) constructor to generate a temporary object and then call Book (const book&) to copy the temporary object to the book. And the second sentence will call the book (const char*) and then finish the thing. If you want to verify their differences, you can implement the book class and set the book (const book&) to a private method (to prevent the compiler from automatically optimizing), then you will find that the first statement cannot be executed.
Copy-assignment operator
copy-assignment Operator: to write this method is to overload the = operator.
The return value of 1,copy-assignment operator is typically a reference to its left operand (left-hand operand), which is determined to make the behavior of object more like a built-in type.
1 class foo{2public:3 operator= (const foo&); 4 // ... 5 };
When copy-assignment operator call occurs
The answer is obviously when you use the = operator, but it's important to note that
Copy-assignment is not called when initializing operator
Copy-assignment is not called when initializing operator
Copy-assignment is not called when initializing operator
Important things to say three times, for example as follows
1 std::string s; 2 std::string s1 = s; // initializes the S1, calling copy constructor 3 s1 = s; // to assign a value to S1, call copy-assignment operator
destructor
destructor:The destructor has two parts, the function body and the destruction part, which is written by the class writer stating what needs to be done, the latter is implicit and does not require the programmer's concern, in function After the body executes automatically, the non-static data members of the class are destroyed.
1, because destructor has no parameters, it cannot be overloaded.
1 class foo{2public:3 ~Foo (); 4 // ... 5 };
When destructor calls occur
1 when the scope of object (scope) is exceeded.
2, when the container is destroyed (container), the element inside will also follow the call of its own destructor to destroy.
3, when you use delete manually.
4, temporary variables created by an expression will automatically be called destructor after the expression is executed and destroyed.
5, if a member of a class has destructor itself, it will call its own destructor when the class is destroyed.
About the version that the compiler automatically provides (synthesized)
synthesized copy constructor: Even if we provide other versions of copy constructor, the compiler will still provide this version of copy constructor to us, It copies non-static members to the created object in turn, the array works correctly, and its own copy constructor is called for the class type.
synthesized copy-assignment operator: behaves like synthesized copy constructor, copying non-static members to the left operand in turn.
synthesized destructor:the function body of destructor is empty.
About when we need to customize the three methods above
1, when the need for destructor, the above three methods are needed.
2, copy-assignment operator is also required when copy constructor is required, and vice versa.
And when we need to delete our dynamically allocated memory, we use destructor.
When we need to make a deep copy, we use another two, such as copying the elements pointing to the pointer and so on.
About the use of delete and default
We can use the default display to declare that we want to use the defaults version of the copy control, or we can use the delete display declaration We do not need this kind of method to prevent the object from the related copy and assignment operation.
1, we can delete all methods except destructor to show that the object cannot be manipulated, and delete can only be written where a declaration occurs.
2, we can use the default display declaration for all functions that have a default version, we need this version, and default can be written in the place of the method declaration, where the method is defined.
1 classfoo{2 Public:3Foo () =default;//explicit instructions for using the default version4Foo (Constfoo&) =Delete;//Delete copy constructor5foo&operator=(Constfoo&) =Delete;//Delete copy-assignment operator6~foo () =default;//explicit instructions for using the default version7 voidMyfuntion () =Delete;//Delete your own method8 //...9};
C++-copy constructor, copy-assignment operator, destructor