The difference between the member initialization list and the constructor body detailed parsing _c language

Source: Internet
Author: User

Answer one of the other questions in the forum

The C + + primer has this passage when speaking about constructor initialization lists:
Whether you initialize members in the constructor initialization list or assign values to them in the constructor body, the end result is the same. The difference is that the constructor initializes the data member with the version of the list, and there are no constructors that define the initialization list to assign values to the data members in the constructor body.

What is the meaning of the initialization data member and the value assigned to the data member here? What's the difference?

I know that there is a difference when a data member has a default constructor, but what about other types of members? Does the initialization and assignment of other type members differ?
=========================================================================
That's what it means:
First, classify the data members by type
1. Built-in data types, composite types (pointers, references)
2. User-defined type (class type)

Sub-situation Note:
For type 1, in the member initialization list and the constructor body, the performance and results are the same
For type 2, the results are the same, but there is a big difference in performance

Because the data member object of the class type is already constructed after entering the function body, that is, the task of constructing the object at the member initialization list is to invoke a constructor that, after entering the function body, is to assign the already constructed class object and call a copy assignment operator to complete (if not provided, Use the compiler-supplied default by member assignment behavior)

Give an example to illustrate
Class A;
Class B
{public:
B () {a = 3;}
Private
A A;
}

Class A
{public:
A () {}
A (int) {value = 3;}
int value;
}

As above, we make the value of a object 3, call a constructor of a and a default copy assignment to achieve the goal
B::b (): A (3) {}
Like this, only a constructor is called to reach the desired object, so the performance is good

Reprint an article of others

My question is about initializing C + + class members. I've seen a lot of that code (including in your column):

Copy Code code as follows:

Csomeclass::csomeclass ()

{

x=0;

Y=1;

}


And somewhere else it's written in the following way:
Copy Code code as follows:

Csomeclass::csomeclass (): X (0), Y (1)

{

}


Some of my programmer friends say the second approach is better, but they don't know why. Can you tell me the difference between these two kinds of member initialization methods?

Reply

Technically, your programmer friend is right, but in most cases, there is no difference in the two. There are two reasons why we choose the second syntax, which is called the member initialization list: One reason is necessary, the other is just for efficiency.

Let's first look at the first reason-necessity. Imagine that you have a class member, which is itself a class or struct, and has only one constructor with one parameter.

Copy Code code as follows:

Class Cmember {

Public

Cmember (int x) {...}

};


Because Cmember has an explicitly declared constructor, the compiler does not produce a default constructor (without arguments), so there is no integer that cannot create an instance of Cmember.

cmember* pm = new Cmember; error!!
cmember* pm = new Cmember (2); Ok

If Cmember is a member of another class, how do you initialize it? You must use the member initialization list.

Copy Code code as follows:

Class CMyClass {

Cmember M_member;

Public

CMyClass ();

};

You must use the member initialization list

Cmyclass::cmyclass (): M_member (2)

{

•••

}


There is no other way to pass parameters to M_member, if the member is a constant object or the reference is the same. Depending on the rules of C + +, constant objects and references cannot be assigned, they can only be initialized.

The second reason is because of efficiency considerations when the member class has a default constructor and an assignment operator. The CString of MFC provides a perfect example. Suppose you have a class CMyClass with a CString type of member M_STR, you want to initialize it to "yada yada." You have two options:

Copy Code code as follows:

Cmyclass::cmyclass () {

Using assignment operators

Cstring::operator= (LPCTSTR);

M_STR = _t ("yada yada");

}

Working with class member lists

and constructor cstring::cstring (LPCTSTR)

Cmyclass::cmyclass (): M_str (_t ("yada yada"))

{

}


Is there any difference between them? Yes. The compiler always ensures that all member objects are initialized before the constructor body executes, so the code compiled in the first example invokes CString:: CString to initialize the M_STR, which is done before the control arrives at the assignment statement. In the second example, the compiler produces a call to CString:: CString (LPCTSTR) and passes "yada yada" to the function. The result is that two CString functions (constructors and assignment operators) are called in the first example, and only one function is called in the second example. This is irrelevant in the case of CString, because the default constructor is inline, and CString simply allocates memory for the string when it is needed (that is, when you actually assign the value). However, in general, repetitive function calls are a waste of resources, especially when constructors and assignment operators allocate memory. In some large classes, you might have a constructor and an assignment operator that calls the same init function that allocates a lot of memory space. In this case, you have to use the initialization list to avoid allocating two of times of memory. There is no performance difference between the initialization list and the assignment in the constructor body, under the internal type such as ints or longs or other types that do not have constructors. Regardless of the method, only one assignment will occur. Some programmers say you should always use initialization lists to keep good habits, but I've never found any difficulty in translating between the two methods as needed. In the programming style, I tend to use assignments in the body, because there is more space to format and add comments, you can write such a statement: x=y=z=0;

or memset (this,0,sizeof (this));

Note that the second fragment is absolutely non object oriented.

When I think about initializing a list, there's a strange feature I should warn you about, it's about C + + initialization class members, which are initialized in the order they are declared, not in the order in which they appear in the initialization list.

Copy Code code as follows:

Class CMyClass {

CMyClass (int x, int y);

int m_x;

int m_y;

};

Cmyclass::cmyclass (int i): m_y (i), m_x (m_y)

{

}


You might think that the code above will do the m_y=i first, then do the m_x=m_y, and finally they have the same value. But the compiler initializes the m_x first, then the m_y, because they are declared in this order. The result is that m_x will have an unpredictable value. My example design to illustrate this point, but this bug will be more natural to appear. There are two ways to avoid it, one is always to declare a member in the order that you want them to be initialized, and the second is, if you decide to use the initialization list, always list the members in the order they are declared. This will help to eliminate confusion.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.