Details the differences and implementations between constructors copy constructors and assignment functions in C++

  • 2020-06-15 09:50:40
  • OfStack

C++ 1 creates objects, copies or assigns them in three ways: constructor, copy constructor, and assignment. The following is a detailed comparison of the differences between the three and their implementation

1. Constructor

A constructor is a special class member function that is called when an object of a class is created to initialize and allocate memory for the data members of the class. (The constructor name must be exactly the same as the class name)

Let's start by saying which default member functions the compiler adds to the next empty class of C++

The default constructor and copy constructor

The destructor

Assignment function (assignment operator)

The value function

** The compiler inserts these functions even if the program does not define any members!

Note: constructors can be overloaded, can be multiple, and can take arguments; There is only one destructor and it cannot be overloaded with no arguments

The default constructor takes no arguments and does nothing. When there is no overload of the no-argument constructor,

A a USES the default constructor to create an object

The following code is an implementation of constructor overload

<span style="font-size:14px;">class A
int m_i;
 Cout<< "No argument constructor" <<endl;
A(int i):m_i(i) {} // Initialization list 

2. Copy the constructor

The copy constructor is unique to C++, which is a special constructor that constructs and initializes another object based on an object of the same class.

When the copy constructor is not overridden, an object is created with the default copy constructor

A a;

A b(a);

A b = a; Copy constructors to create the object b

Emphasis: b object does not exist, it is constructed and initialized with a object!!

First, when the copy constructor is called:

In C++, three objects need to be copied, at which point the copy constructor is called

1) 1 object is passed into the function body as a value 2) 1 object is returned from the function by value passing 3) One object needs to be initialized by another object

When the compiler generates the default copy constructor:

1) If the user does not have a custom copy constructor and the copy constructor is used in the code, the compiler generates the default copy constructor. But if the user defines a copy constructor, the compiler does not generate it. 2) If the user defines a constructor, but not a copy constructor, and the copy constructor is used in the code, the compiler will also generate the default copy constructor.

Because the default copy constructor provided by the system works as a memory copy, or shallow copy. If the object is used with an object that needs to be released manually, then there is a problem and you have to manually override the copy constructor to implement a deep copy.

Here's how deep and shallow copies work:

Shallow copy: If the copied object references an external content (such as data allocated on the heap), then copying the object with the old and new objects pointing to the same external content is a shallow copy. (Although the pointer is copied, the spatial content it points to is not copied. Instead, it is Shared by two objects. The two objects are not independent. Deep copy: If a separate copy of an external object is made for the new object while copying this object, this is called a deep copy.

Copy constructor overload declarations are as follows:

A (const A & other)

The following is the implementation of the copy constructor:

<span style="font-size:14px;">class A
 int m_i
 A(const A& other):m_i(other.m_i)
 Cout<< "Copy constructor" <<endl;

3. Assignment function

An assignment function of a class is used when an object of that class assigns values to another object of that class.

When no assignment function (assignment operator) is overridden, assignment is performed by default

A a;

A b;


Emphasis: here a,b object is already existing and assigned to b with a object!!

The overload declaration for the assignment operation is as follows:

A & operator = (const A & other)

Copy constructors are often confused with assignment functions, but here's a closer look at the difference:

1) The copy constructor initializes a block of memory for each object, which is the memory area of the new object, and the assignment function assigns an object that has already been initialized.

<span style="font-size:14px;">class A;
A a;
A b=a;  // Calling the copy constructor ( b There is no) 
A c(a) ;  // Call the copy constructor 
class A;
A a;
A b;  
b = a ;  // Call the assignment function (b There are )</span>

2) 1 Generally, when data members contain pointer objects, two different processing requirements need to be considered: one is to copy pointer objects, and the other is to reference pointer objects. Copy constructors are mostly copies, while assignment functions are reference objects

3) Not one. The copy constructor starts with a constructor that generates an object by initializing it with an argument. The assignment function assigns 1 new object to 1 original object, so if there is memory allocation in the original object, the memory should be released first, and check whether the two objects under 1 are the same object, if so, do nothing, return directly. (These points are reflected in the String implementation code below)

!!!!!!!!! If you do not want to write copy constructors and assignment functions, and do not allow others to use the default functions generated by the compiler, the easiest way is to declare copy constructors and assignment functions as private functions without writing code. Such as:

<span style="font-size:14px;">class A
 A(const A& a); // Private copy constructor 
 A& operate=(const A& a); // Private assignment functions 

If the program is written this way, an error will occur:

<span style="font-size:14px;">A a;
A b(a); // A private copy constructor was called and a compilation error occurred 
A b;
b=a; // A private assignment was called, and a compilation error occurred </span>

So if there are Pointers or references to variables or objects in the class definition, it is best to override copy constructors and assignment functions to avoid potential errors.

The following is the implementation of string class as an example, complete writing the ordinary constructor, copy constructor, assignment function implementation. See my other blog post for the basic implementation of the String class.

<span style="font-size:14px;">String::String(const char* str)  // Ordinary constructor 
 if(str==NULL)    // if str  for NULL , just to save 1 Empty string "" 
 m_string=new char[1];
 *m_string ='\0';
 m_string= new char[strlen(str)+1] ;  // Allocate space 
String::String(const String&other)  // Copy constructor 
 cout<<"copy construct"<<endl;
 m_string=new char[strlen(other.m_string)+1]; // Allocate space and copy 
String & String::operator=(const String& other) // Assignment operator 
 cout<<"operator =funtion"<<endl ;
 if(this==&other) // If the object and other Is to use 1 Object, returns itself directly 
 return *this;
 delete []m_string; // I'm going to free up the old memory 
 m_string= new char[strlen(other.m_string)+1];
 return * this;

Remember three sentences:

The constructor is called when the object does not exist and is not initialized with another object.

An object that does not exist and is initialized with another object is a copy constructor (there are three cases where it is used!).

An object exists and is assigned to another object, which is an assignment function.

Above for my combination of a lot of materials and books sorted out, will be the core of the point of the system out, all their own according to the rules, now everyone on the ordinary constructor, copy constructor, assignment function of the distinction and implementation should be clear.

Related articles: