An example of the constructor in C++

  • 2020-05-30 20:54:57
  • OfStack

An example of the constructor in C++

The knowledge of c++ constructors has been introduced in various c++ textbooks, but beginners often pay little attention to observe and summarize the features and usage of various constructors, so here I summarize the features of various constructors in c++ 1 based on my own c++ programming experience, and attach examples, hoping to help beginners.

1. What is a constructor


class Counter
{
 
public:
  //  class Counter Constructor of 
  //  Features: class name as function name, no return type 
  Counter()
  {
    m_value = 0;
  }
     
private:   
  //  Data members 
 int m_value;
}

When the class object is created, the compiler object allocates memory space and automatically calls the constructor - > The constructor initializes the member

eg: Counter c1;

The compilation system allocates memory space for each data member of the object c1 (m_value), and calls the constructor Counter() to automatically initialize the m_value value of the object c1 to 0

Therefore: constructor function: initializes the data member of the object.

2. Types of constructors


class Complex 
{     
 
private :
  double m_real;
  double m_imag;
 
public:
 
  //  No-argument constructor 
  //  If you are creating 1 You didn't write any constructors , The system will automatically generate the default no-argument constructor, which is empty and does nothing, right 
  //  As long as you write 1 Something down here 1 The kind of constructor that the system doesn't automatically generate 1 Default constructors, if desired 1 Such an argument - free constructor needs to be written explicitly 
  Complex(void)
  {
     m_real = 0.0;
     m_imag = 0.0;
  } 
     
  // 1 Generic constructor (also known as overloaded constructor) 
  // 1 Generic constructors can take various parameter forms ,1 You can have more than one class per class 1 General constructors, provided the number or type of arguments is different (based on c++ Principle of overloaded function) 
  //  You can also write 1 a  Complex( int num) The constructor of 
  //  When creating an object, different constructors are called depending on the parameters passed in 
  Complex(double real, double imag)
  {
     m_real = real;
     m_imag = imag;     
   }
   
  //  Copy constructor (also known as copy constructor) 
  //  The copy constructor parameter is a reference to the class object itself, which is used as a basis 1 Two existing objects are copied out 1 Two new objects of this class, 1 The value of the data member of an existing object is usually copied in a function 1 To the newly created object 
  //  If the write copy constructor is not shown, it is created by default 1 Copy constructor, but when there is a pointer member in the class, there is a risk that the system will create this copy constructor by default, for specific reasons please check about   "Shallow copy"   , "deep copy" article discussion 
  Complex(const Complex & c)
  {
    //  The object c The data member values in the 
    m_real = c.m_real;
    m_img = c.m_img;
  }      
 
  //  The type conversion constructor, according to 1 Object of the specified type 1 Object of this class 
  //  The following will be based on 1 a double The object of type is created 1 a Complex object 
  Complex::Complex(double r)
  {
    m_real = r;
    m_imag = 0.0;
  }
 
  //  The equals operator is overloaded 
  //  Notice that this copy constructor, similar to the copy constructor, will = The value of this class object on the right is copied to the object on the left of the equal sign. It is not a constructor, and objects on both sides of the equal sign must have been created 
  //  If the write is not shown = When the operator is overloaded, the system is also created 1 A default = Operator overload, just do 1 Some basic copy work 
  Complex &operator=(const Complex &rhs)
  {
    //  First, check whether the object to the right of the equals sign is the object to the left, if the object itself , I'm gonna go straight back 
    if ( this == &rhs ) 
    {
      return *this;
    }
       
    //  Copy the member on the right of the equals sign into the object on the left 
    this->m_real = rhs.m_real;
    this->m_imag = rhs.m_imag;
       
    //  I'm going to pass out the object on the left hand side again 
    //  The purpose is to support company etc  eg:  a=b=c  The system runs first  b=c
    //  Then run  a= ( b=c The return value of the , This should be a copy c After the values of b object )  
    return *this;
  }
};

Here's how each constructor is used using the class objects defined above:


void main()
{
  //  The no-argument constructor is called, and the initial value of the data member is assigned to 0.0
  Complex c1 . c2;
 
  //  call 1 General constructor, the initial value of the data member is assigned to the specified value 
  Complex c3(1.0,2.5);
  //  You can also use the following form 
  Complex c3 = Complex(1.0,2.5);
     
  //  the c3 The value of the data member assigned to c1
  //  Due to the c1 It has been created in advance, so no constructor is called 
  //  Can only call  =  The sign operator overloads the function 
  c1 = c3;
     
  //  The type conversion constructor is called 
  //  The system first calls the type conversion constructor, which will 5.2 Created as 1 A temporary object of this class, and then the equals operator overload is called to assign this temporary object a value to c1
  c2 = 5.2;
    
  //  Call the copy constructor (  There are two ways to do this ) 
  Complex c5(c2);
  Complex c4 = c2; //  Pay attention to and  =  Operator overload discrimination , Here, the object to the left of the equal sign is not created in advance, so you need to call the copy constructor c2    
     
}

3. Think and test

(1) why can a function directly access the private member of the object c?


Complex(const Complex & c)
{
  //  The object c The data member values in the 
  m_real = c.m_real;
  m_img = c.m_img;
}

(2) challenge to understand the difference between a quote and a pass


Complex test1(const Complex& c)
{
  return c;
}
  
Complex test2(const Complex c)
{
  return c;
}
  
Complex test3()
{
  static Complex c(1.0,5.0);
  return c;
}
  
Complex& test4()
{
  static Complex c(1.0,5.0);
  return c;
}
  
void main()
{
  Complex a,b;
  
  //  How many times will the constructor be called during the execution of the following functions? What constructor is called? 
   
  test1(a);
  test2(a);
   
  b = test3();
  b = test4();
   
  test2(1.2);
   
  //  Can the following statement be wrong? 
  test1(1.2);   
   
  //test1( Complex(1.2 ))  ? 
}

4. Shallow copy and deep copy

Mentioned above, if there is no custom copy constructor, then the system will create the default copy constructor, the system creates a default copy constructor will only perform a "shallow", the value of the object to copy the data members of 11 assigned to the newly created object, if the data members of the class has a pointer member, will make the new object pointer points to address with the copy of the object the pointer points to the same address, delete twice when the pointer leads to repeated delete and error. Here's an example:


#include <iostream.h>
#include <string.h>
class Person 
{
public :
     
  //  The constructor 
  Person(char * pN)
  {
    cout << "1 The general constructor is called  !\n";
    m_pName = new char[strlen(pN) + 1];
    // Dig through the heap 1 Memory blocks pN The string referred to 
    if(m_pName != NULL) 
    {
      // if m_pName Is not a null pointer, then put the parameter pointer pN The reference string is copied to it 
       strcpy(m_pName ,pN);
    }
  }    
    
  //  The default copy constructor created by the system, making only bit-mode copies 
  Person(Person & p)  
  { 
    // Make two Pointers to the same string 1 Address location      
    m_pName = p.m_pName;     
  }
 
  ~Person( )
  {
    delete m_pName;
  }
     
private :
  char * m_pName;
};
 
void main( )
{ 
  Person man("lujun");
  Person woman(man); 
   
  //  As a result,   man  and   woman  All Pointers to the same thing 1 An address 
   
  //  When the function ends the destructor 
  //  with 1 The address is delete two 
}
 
 
//  Let's design our own copy constructor and implement a "deep copy" that does not point to the same pointer 1 Address, but reapply 1 Block memory to the new object's pointer data member 
Person(Person & chs);
{
   //  With the operator new Allocate space for the pointer data member of the new object 
   m_pName=new char[strlen(p.m_pName)+ 1];
 
   if(m_pName)     
   {
       //  Duplicate content 
      strcpy(m_pName ,chs.m_pName);
   }
  
  //  Of the newly created object m_pName With the original object chs the m_pName No longer point to the same 1 Address the 
}

If you have any questions, please leave a message or come to the site community to exchange discussion, thank you for reading, hope to help you, thank you for your support of the site!


Related articles: