C++ basic syntax: constructor initializes list

  • 2020-04-02 01:45:10
  • OfStack

C++ provides an initialization list of class members in a class

Class objects are constructed in this order:
1. Allocate memory and implicitly/explicitly initialize each data member when the constructor is called
2. Perform general calculations in the constructor after entering the constructor

There are two reasons to use an initialization list:

1. This must be done:
If we have a class member, it itself is a class or a structure, and the member it is only a constructor with parameters, and there is no default constructor, then to the class member is initialized, it must be called with members of the class constructor parameters, if there is no initialization list, so he will not be able to complete the first step, will be an error.


class  ABC
  ... {
 public :
          ABC( int  x, int  y, int  z);
 private :
           int  a;
           int  b;
           int  c;
 } ;
 class  MyClass
  ... {
 public :
          MyClass():abc( 1 , 2 , 3 ) ... {} 
 private :
         ABC abc;
 } ;

Because ABC has a constructor with arguments displayed, it cannot rely on the compiler to generate a no-argument constructor, so it cannot create an ABC object without three ints.

The ABC class object is a member of MyClass. If you want to initialize the object ABC, you can only initialize the list with the member. There is no other way to pass the parameters to the ABC class constructor.

Another situation is that when a class member contains a const object, or a reference, they must also be initialized by the member initializer list, because both objects are initialized immediately after the declaration, and in the constructor, the assignment to them is not allowed.

2. Efficiency requires this:
, according to the construction of class objects into the constructor body, is calculated, is the value assigned to their operation, obviously, assignment and initialization is different, which reflects the differences of efficiency and initialization if not members of the class table, then the class of his own class members respectively is an implicit default constructor calls, and a copy operator call, if it is a class object, efficiency is not guaranteed to do so.

Note: The constructor initializes the data members, whether or not they appear in the constructor's member initialization list, in the same order that they were declared, regardless of the order of the list Therefore, special attention should be paid to ensure that they are in the same order so as to ensure their efficiency.

For clarity, suppose there is a class:


class foo{
   private :
    int a, b;
};

1. Foo (){} and foo(int I = 0){} are considered default constructors because the latter is the default parameter. You can't have both.

2. The constructor list is initialized not in the order of the list, but in the order of the variable declaration. So for example, in foo, where a comes before b, then we're going to construct a and then construct b. So whatever foo () : a, b + 1), b (2) {} or foo () : b (2), a (b + 1) {} will not let a desired value. It would be better to declare b first and then a.

3. Constructor list can be initialized to const members. So foo has an int const c; So foo(int x) : c(x){} can assign the c value to x. However, it is important to note that c must have a value in every constructor, if any.

4. In inheritance, only the initialization list can construct the private member of the parent class. For instance


class child : public foo{
}

The constructor in foo says :foo (int x) {a = x; }.
And inside the child, I'll say child(int x){foo(x); } does not pass compilation. Only if the parent class is initialized as foo(int x) : a(x){} and the child class is constructed as child (int x) : foo(x){}.

C++ initializes the members of a class, not only with a constructor, but also with a list of class members. MFC USES this approach a lot. For example, some beginners may not understand the following code:
Class A,
{
  Public:
      Int member_var; // member variables
      (A);                       // constructor
}
A: : (A) : member_var (0)
{
}

They felt that the definition of the constructor should be as follows:
A: : (A)
{
    Member_var = 1;
}
It works both ways. But in some cases, you can only use the first one, and it's usually more efficient to use the first one.

In fact, the first method is actually initialization, while the "=" operation implemented in the constructor is actually assignment. All the difference between the two methods starts here. Here's the difference:

1. We know that the normal variable compiler initializes for you by default. They can be initialized and assigned, while const can only be initialized and not assigned according to its meaning. Otherwise it is indistinguishable from a variable. So const members can only "initialize" them with a list of member initializers, not "assign" them within the constructor.

2. We know that the initialization of a class's object is done by calling its constructor. If no constructor is written, the compiler will generate one for you by default. If you customize the constructor with arguments, the compiler will not generate the default constructor. So the initialization of the object of this class must have parameters. If the object of such a class is a member of another class, then in order to initialize the member, you must pass an argument to the constructor of the object of that class. Similarly, if you use "=" in the constructor of the class that contains it, you are actually "assigning" to the object rather than "initializing" it. So all constructors in a class have arguments, so if such a class is a member variable of another class, you must initialize it explicitly, and you can only initialize it by the member initializing the list. Such as:


class B
{
......
}
class A
{
  public:
  B member_b;
  A();
}
A::A():B(...) //You have to initialize it explicitly because of all its constructors
              //They all have parameters, and then they can be assigned.
{
  B=... ;  //Because as written above, it is already initialized to be assigned, otherwise an error.
}

Initialization sequence:

class test 
{ 
       const int a; 
       std:string str; 
       object o; 
       test():str( " df " ),o(null) ,a(0) 
{ 
}     
}; 

The yellow ones are both initialization lists, which are called before the constructor is formally called, and their initialization order is not based on the order in which they appear in the initialization list, but on the order in which they are declared. Above:

The initialization sequence is: a, STR, o;

Typically used to initialize constant-type, statically typed data, or data that cannot exist independently


Related articles: