Initialization list of c++ constructors

  • 2020-04-02 01:14:09
  • OfStack

First, run the C++ code in the figure below. What is the output?


class A
{
private:
 int n1;
 int n2;
public:
 A(): n2(0) , n1(n2 + 2)
 {
 }
 void Print()
 {
  cout<<"n1:"<<n1<<",n2:"<<n2<<endl;
 }
};
int main(void)
{
 A a;
 a.Print();
 return 0;
}

The answer:
The output n1 is a random number, n2 is 0. In C++, member variables are initialized in the same order that variables are declared in the type, regardless of their order in the constructor's initialization list. So in this case, n1 is going to be initialized first, and the argument to n1, n2, is not initialized yet, is a random value, so n1 is just a random value. When n2 is initialized, it is initialized according to parameter 0, so n2=0.

The initializer list for the constructor specifies only the values for initializing the members, not the order in which these initializations are executed. The order in which a member is initialized is the order in which the members are defined. The first member is initialized first, then the second, and so on. That is, the C++ compiler can easily get the constructor's argument list, get the arguments, and then initialize the member variables according to the order in which they are declared (this is because the declared variables may depend on the declared member variables, so there is a declared first initialized, declared later initialized).

You might see this and think, oh, this is a pain, when a data member of a class is initialized based on another data member, the order in which the list is initialized must not be inconsistent with the order in which the member variables are declared, otherwise there will be an unexpected error.

That's true, so one would think, well, I'm just going to put everything that initializes the list into the constructor's body and assign values to the data members, which is fine, but sometimes initializing the list of constructors is necessary.

Some data members must be initialized in the constructor initialization list. For such members, assigning values to them in the constructor body does not work. A member of a class type without a default constructor, as well as a member variable of type const and a member variable of reference type, must be initialized in the constructor initialization list, regardless of the type.
For example, the following constructor definition is wrong:


class A
{
private:
 int i;
 const int j;
 int &k;
public:
 A(int ii)
 {
  i = ii;
  j = ii;
  k = ii;
 }
};

Keep in mind that , you can initialize const objects or objects of reference type, but you cannot assign values to them. To complete the initialization before starting to execute the constructor's body, the only chance to initialize a data member of a const or reference type is in the constructor's initialization list.
For example, the following constructor definition is correct:

class A
{
private:
 int i;
 const int j;
 int &k;
public:
 A(int ii) : i(ii) , j(i) , k(ii)
 {
 }
 A() : j(0) , k(i)
 { }
};
int main(void)
{
 A a;
 return 0;
}


Related articles: