Copy constructor and no-argument constructor, deep and shallow copy


 1. What is a constructor 
 

       1.1 What is a constructor? This, you can say anything, its main function is initialization, it can also be said that it is an initialization format method provided by C++, I don't think it is so magical and awesome.

Specifically, there is no return value, (no, not void), the function name is the same as the class name, when the object is created and the memory is allocated, it is initialized and can be overloaded. This is not when my c structure was created. Braces are initialized, [constructors are actually mainly used for compiler calls] I think this sentence is very imprecise, and it is also nonsense. Many people write this in their blogs. If you distinguish a little, the compiler will have a calling function. When the code in your program is called and executed, it depends on when you are compiled, when you open it for execution, then allocate the object space, and then call the constructor to initialize the members. .
This sentence should be the calling code of the constructor, and the compiler will generate it for you. Without writing a constructor, the compiler will also generate code for you instead of calling it.

1.2 There are many initialization methods for constructors

# include<iostream>
# include <string>
using namespace std;

class Test
{

public :
	int a;
	int b;
	int c;
	Test(int a)
	{
	  this->a=a;
	}
};

int main (void)
{

    Test oo(4); //Method 1
    Test o1=Test(4); //Method 2
    Test o2 =4; // Method 3

return 0;
}

2. C++ provides two special constructors by default, that is, the no-argument constructor and the copy constructor.

The special thing is that it is automatically generated, of course, it will be generated when you don't write it. The parameterless constructor is very common, that is, the constructor without parameters, and the copy constructor, mainly because the parameter of the constructor is the reference of the current class. , what does that mean? It means that when we pass parameters to the constructor, we enter a reference to a class, and then initialize the current parameter to the value inside the passed reference. It sounds difficult. In fact, it is simply a copying process. For example, we need two objects of a class, and assign the initialization content of object 1 to object 2. What does the process look like?


Of course, the ink on the picture is actually very simple. What kind of objects, classes, etc. are there? (Of course, I am not saying that it is not good, it is easy to be deceived when we need to see through), or it defines two spaces, One of the spaces has been initialized, and then the first address of one of the spaces is taken, and the value of the initialized member is obtained by offset addressing, and assigned to each corresponding member of the uninitialized space. Of course, you may say that you are thinking of C. People have proper nouns. In fact, the reason why many things cannot be seen through is often that you are blinded by his lofty appearance. The reason why I dare to say that, No matter how awesome he is, he still has to generate assembly code in the end. Let's disassemble it and look at it. In fact, the underlying implementation is as I described above.

# include<iostream>
# include <string>
using namespace std;

class Test
{

public :
	int a;
	int b;

	Test(int a,int b)
	{
	  this->a=a;
	  this->b=b;
	}

	Test(const Test &test )
	{
	  a=test.a;
	  b=test.b;
	}
};

int main (void)
{

	Test yes (4,5);
    Test &ll=oo;
    Test  xx= ll;
	cout<< "对象oo的值  "<<oo.a<<" "<<oo.b<<endl;
    cout<< "对象xx的值  "<<xx.a<<" "<<xx.b<<endl;

return 0;
}
result:
The value of object oo 4 5
The value of object xx 4 5
Press any key to continue

3. Well, as we said above, the characteristic of his copy constructor is a simple copy. We call him a shallow copy. Of course, now that he is a superficial copy, you may disagree. Everyone has copied it. What else? Superficial not superficial. Let's look at the code below

# include<iostream>
# include <string>
using namespace std;


class Test
{


public :
	int *a;
	int b;


	Test(int a,int b)
	{
	  this->a=new(int);
	  this->b=b;
	}


	Test(const Test &test )
	{
	  a=test.a;
	  b=test.b;
	}
};


int main (void)
{
   
      Test yes (4,5);
    Test &ll=oo;
    Test  xx= ll;
	cout<< "对象oo的值  "<<oo.a<<" "<<oo.b<<endl;
    cout<< "对象xx的值  "<<xx.a<<" "<<xx.b<<endl;


return 0;
}


Output result:
The value of object oo 00852FB8 5
The value of object xx 00852FB8 5
Press any key to continue

The result seems to be nothing wrong, but the problem is persuading, that is, the member pointer in the object xx, should it be executed the same as oo, if it is code-wise
There is no problem, the result is the same, but in practice, this may happen, because our copy constructor is too stupid, it just knows the copy, I don't know that I also allocate a 4-byte space of my own to my a, but I pointed my a to the allocated space of other people's oo. Of course, there is no absolute in everything, you have to do it intentionally and it is not wrong, I am afraid that you originally wanted to have their own space, and the result. . . . That said, why is it a superficial copy, because he can't tell the difference.
The solution is simple. Let's change the constructor
# include<iostream>
# include <string>
using namespace std;


class Test
{


public :
	int *a;
	int b;


	Test(int a,int b)
	{
	  this->a=new(int);
	  this->b=b;
	}


	Test(const Test &test )
	{
	  a=new(int);
	  b=test.b;
	}
};


int main (void)
{
   
	Test yes (4,5);
    Test &ll=oo;
    Test  xx= ll;
	cout<< "对象oo的值  "<<oo.a<<" "<<oo.b<<endl;
    cout<< "对象xx的值  "<<xx.a<<" "<<xx.b<<endl;


return 0;
}


result

The value of object oo 00592FB8 5
The value of object xx 00592E50 5
Press any key to continue

Well, this is a deep copy

August 28, 2017 00:14:16 I can finally sleep

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325536851&siteId=291194637