constructors, destructors, and assignment functions are the most basic functions of each class. They are so common that they are easy to careless, but these seemingly simple functions are as dangerous as a sewer without a lid.
Each class has only one destructor and one assignment function, but it can have multiple constructors (one copy constructor, others called ordinary constructors).
For any class A, if you do not want to write the above functions, the C + + compiler will automatically generate four default functions for a, for example:
A (void); Default parameterless constructor
A (const a &a); The default copy constructor
~a (void); Default destructor
A & operate = (const a &a); The default assignment function
This begs the question, since the function can be generated automatically, why should the programmer write? The reasons are as follows:
<1> if the "default parameterless constructor" and "default destructor" are used to give up the chance of autonomous "initialization" and "purge", the C + + inventor Stroustrup's kindness is wasted.
<2> "Default copy Constructors" and "default assignment Functions" are all implemented using "bit copy" rather than "copy of value", and if the class contains pointer variables, these two functions are doomed to error.
C + + default constructor:
1, each class must have a constructor, otherwise it is impossible to create objects;
2, if the programmer does not provide any constructors, C + + provides a default constructor, the default constructor is a parameterless constructor, it is only responsible for creating objects, do not do any initialization work;
3. As long as Programer defines a constructor (whether it is a parameterless or a parametric construct), C + + no longer provides the default default constructor. That is, if you define a constructor for a class with parameters and you want to have no parameter constructor, you must define it yourself;
4, similar to the variable definition, when creating an object with the default constructor, if you create a global object or a static object, the object's bit pattern is all 0, otherwise the object value is random.
C + + default copy constructor:
1. The default copy constructor executes in the same order as other user-defined constructors, executing the construction of the subclass after the Father's class.
2. Copy constructor performs the action of member copy (memberwise copy) for each data member in the class.
3. If the data member is an instance of a class, call the copy constructor of this class.
4. If the data member is an array, perform a bitwise copy of each of the pairs.
5, if the data member is a number, such as int,double, then call the system built-in assignment operator to assign the value.
Take a look at the following code:
#include <iostream> #include <string>using namespace Std;class student{public:student () {cout << " Constructor 1 "<< Endl;} Student (int k) {cout << "constructor 2" << endl;i = k;} Student (Student const &m) {cout << copy constructor << endl;i = M.I * (-1);} void P () {cout << i << Endl;} ~student () {cout << destructor << Endl;} Protected:int i;}; int main (int argc, char **argv) {Student s (9818);//Call constructor 2S.P (); Student T (s);//Call copy constructor T.P (); Student k = s;//Call copy constructor K.P (); Student *p = new Student (s);//Call copy constructor p->p (); Student m;//Call Constructor 1m = s;//Assignment Operation M.P (); return 0;}
Operation Result:
Constructor 2 9818 copy Constructor -9818 copy constructor -9818 copy constructor -9818 constructor 19818 destructor for destructor destructor of destructor structure function
Let's discuss the problem of shallow and deep copy.
The definition of deep and shallow copies can be easily understood as: If a class has resources (heaps, or other system resources), the process can be called a deep copy when the object of the class is copied (the value that the pointer points to). The case where the object exists but the copy process does not replicate the resource (only the address referred to by the pointer is copied) is considered a shallow copy.
Many people will ask, since the system will automatically provide a default copy constructor to handle the replication, then we do not have to customize the copy constructor Ah, yes, it is not necessary in the ordinary case, but in some cases, the members of the body need to open up dynamic heap memory, If we do not customize the copy constructor and let the system handle it itself, it will cause confusion in the ownership of heap memory. Imagine that one end of the heap address originally belongs to the object A, because the copy process occurs, the B object is a has opened the heap address, once the program generated destruction, the release of the heap, the computer is not clear to whom the address is really belongs to, when the continuous occurrence of two times the destruction of the time of the run error.
For a more detailed explanation of the problem, see the code below.
#include <iostream>#include<string>using namespacestd;classaa{ Public: aa () {cout<<"Call Constructor"<<Endl; F=New Char[Ten]; } ~AA () {cout<<"Call destructor"<<Endl; Delete[] f; } Char*F;};intMainintargcChar**argv) {AA p; printf ("p.f=%p\n", P.F); strcpy (P.F,"Computer"); cout<< P.F <<Endl; AA q (p);//Call the default copy constructorprintf"q.f=%p\n", Q.F); cout<< Q.F <<Endl; strcpy (P.F,"Software"); cout<< P.F <<Endl; cout<< Q.F <<Endl; strcpy (Q.F,"Software"); cout<< P.F <<Endl; cout<< Q.F <<Endl; return 0;}
Operation Result:
Call constructor P.f=003f1048computerq.f= 003f1048computersoftwaresoftwaresoftwaresoftware Call destructor Call destructor
From the example above, we can see clearly that the second object calls the copy constructor, and Q.F obtains the same address value as P.F, which points to the same memory area. At the end of the program, the destructor is called two times, that is, what happens when the same pointer executes two times the delete operation? This could be a disaster that could damage the heap and free memory tables.
So how do we avoid it? Here we need to use a deep copy.
#include <iostream>#include<string>using namespacestd;classaa{ Public: aa () {cout<<"Call Constructor"<<Endl; F=New Char[Ten]; } AA (AAConst&s) {cout<<"Call copy Constructor"<<Endl; F=New Char[Ten]; strcpy (f, S.F); } ~AA () {cout<<"Call destructor"<<Endl; Delete[] f; } Char*F;};intMainintargcChar**argv) {AA p; printf ("p.f=%p\n", P.F); strcpy (P.F,"Computer"); cout<< P.F <<Endl; AA q (p);//call the copy constructor of the userprintf"q.f=%p\n", Q.F); cout<< Q.F <<Endl; strcpy (P.F,"Software"); cout<< P.F <<Endl; cout<< Q.F <<Endl; strcpy (Q.F,"Software"); cout<< P.F <<Endl; cout<< Q.F <<Endl; return 0;}
Operation Result:
Call constructor P.f=00351048Computer Call copy constructor q.f=00351060 Computersoftwarecomputersoftwaresoftware Call destructor Call destructor
Now we can see that p.f and Q.f point to different areas of memory respectively.
From: http://blog.csdn.net/sg131971/article/details/7045278
C + + constructors and copy constructors in a detailed