C + + Learning Log: detailed explanation of C + + constructor

stay C++ In, there is a special member function with the same name as the class name and no return value. It does not need to be explicitly called by the user (nor can the user), but is automatically executed when the object is created. This special member function is the Constructor.

In< Access rights of C + + class members and class encapsulation >In the section, we assign values to the member variables name, age, and score through the member functions setname(), setage(), and setscore(). Although this is effective, it seems a little troublesome. With the constructor, we can simplify this work by assigning values to member variables while creating objects. See the following code (example 1):

#include <iostream>
using namespace std;
class Student{
private:
    char *m_name;
    int m_age;
    float m_score;
public:
    //Declaration constructor
    Student(char *name, int age, float score);
    //Declare normal member functions
    void show();
};
//Define constructor
Student::Student(char *name, int age, float score){
    m_name = name;
    m_age = age;
    m_score = score;
}
//Define normal member functions
void Student::show(){
    cout<<m_name<<"What is your age"<<m_age<<",The result is"<<m_score<<endl;
}
int main(){
    //Pass arguments to constructor when creating object
    Student stu("Xiao Ming", 15, 92.5f);
    stu.show();
    //Pass arguments to constructor when creating object
    Student *pstu = new Student("Li Hua", 16, 96);
    pstu -> show();
    return 0;
}

Operation results:
Xiao Ming's age is 15 and his grade is 92.5
Li Hua's age is 16 and his grade is 96

This example defines a constructor Student(char *, int, float) in the Student class, which is used to assign values to the member variables of three private attributes. To call this constructor, you have to pass arguments while creating the object, and the arguments are surrounded by (), which is very similar to an ordinary function call.

When creating an object on the stack, the argument is after the object name, such as Student stu("Xiao Ming", 15, 92.5f); When creating an object on the heap, the argument is after the class name, such as new Student("Li Hua", 16, 96).

The constructor must be of public property, otherwise it cannot be called when creating an object. Of course, setting the private and protected attributes will not report an error, but it is meaningless.

The constructor has no return value because there is no variable to receive the return value. Even if there is, it is useless, which means:

  • Whether declared or defined, the return value type cannot appear in front of the function name, even void;
  • A return statement cannot exist in a function body.

Overload of constructor

Like normal member functions, constructors are overloaded. A class can have multiple overloaded constructors. When creating an object, judge which constructor to call according to the passed arguments.

The call of constructor is mandatory. Once the constructor is defined in the class, it must be called when creating the object. It is wrong not to call. If there are multiple overloaded constructors, the arguments provided when creating the object must match one of them; Conversely, when creating an object, only one constructor is called.

For the code in example 1, it is wrong to write Student stu or new Student, because the class contains a constructor, but it is not called when creating the object.

Change the code of example 1 and add another constructor (example 2):

#include <iostream>
using namespace std;
class Student{
private:
    char *m_name;
    int m_age;
    float m_score;
public:
    Student();
    Student(char *name, int age, float score);
    void setname(char *name);
    void setage(int age);
    void setscore(float score);
    void show();
};
Student::Student(){
    m_name = NULL;
    m_age = 0;
    m_score = 0.0;
}
Student::Student(char *name, int age, float score){
    m_name = name;
    m_age = age;
    m_score = score;
}
void Student::setname(char *name){
    m_name = name;
}
void Student::setage(int age){
    m_age = age;
}
void Student::setscore(float score){
    m_score = score;
}
void Student::show(){
    if(m_name == NULL || m_age <= 0){
        cout<<"The member variable has not been initialized"<<endl;
    }else{
        cout<<m_name<<"What is your age"<<m_age<<",The result is"<<m_score<<endl;
    }
}
int main(){
    //Call constructor Student(char *, int, float)
    Student stu("Xiao Ming", 15, 92.5f);
    stu.show();
    //Call constructor Student()
    Student *pstu = new Student();
    pstu -> show();
    pstu -> setname("Li Hua");
    pstu -> setage(16);
    pstu -> setscore(96);
    pstu -> show();
    return 0;
}

Operation results:
Xiao Ming's age is 15 and his grade is 92.5
The member variable has not been initialized
Li Hua's age is 16 and his grade is 96

Constructor Student(char *, int, float) assigns a value to each member variable, and constructor Student() sets the value of each member variable to null. They are overloaded relationships. When creating objects according to Student(), member variables will not be given valid values, so member functions setname(), setage(), and setscore() will be called to re assign values to them.

Constructors are widely used in practical development. They are often used to do some initialization work, such as assigning values to member variables, opening files in advance, etc.

Default constructor

If the user does not define a constructor, the compiler will automatically generate a default constructor, but the function body of the constructor is empty, has no formal parameters, and does not perform any operations. For example, for the Student class above, the default generated constructor is as follows:

Student(){}

A class must have a constructor, either user-defined or automatically generated by the compiler. Once the user defines the constructor, the compiler will no longer generate it automatically, no matter how many constructors there are or how many formal parameters there are. In example 1, the Student class already has a constructor Student(char *, int, float), which is defined by ourselves. The compiler will not add an additional constructor Student(). In example 2, we added the constructor manually.

In fact, the compiler generates the default constructor only when necessary, and its function body is generally not empty. The purpose of the default constructor is to help the compiler do initialization, not to help the programmer. This is the internal implementation mechanism of C + +, which is no longer studied here. Beginners can understand it according to the above saying "there must be a default constructor for an empty function body".

The last thing to note is that parentheses can also be omitted when calling a constructor without parameters. For the code of example 2, the object created on the stack can be written as Student stu() or Student stu, and the object created on the heap can be written as Student *pstu = new Student() or Student *pstu = new Student, both of which will call the constructor Student().

This is what we did before. We didn't write parentheses when creating objects. In fact, we called the default constructor.

Keywords: C++ Back-end IoT stm32

Added by tartou2 on Mon, 03 Jan 2022 15:41:27 +0200