Methods and main differences of constructor initialization in C ++

Source: Internet
Author: User

I. My question is about initializing C ++ class members. I have seen a lot of such code (including those in your bar ):
Csomeclass: csomeclass ()
{
X = 0;
Y = 1;
}
In other places, it is written as follows:
Csomeclass: csomeclass (): x (0), y (1)
{
}
Some of my programmers say the second method is better, but they don't know why. Can you tell me the differences between the two types of member initialization methods?

Answer
Technically, your programmers are right, but in most cases, there is no difference between the two. There are two reasons for us to select the second syntax, called the member initialization list: one is mandatory, and the other is only for efficiency considerations.
Let's take a look at the first reason-necessity. Suppose you have a class member, which is a class or structure and has only one constructor with one parameter.
Class cmember {
Public:
Cmember (int x ){...}
};
Because cmember has an explicitly declared constructor, the compiler does not generate a default constructor (without parameters). Therefore, an instance of cmember cannot be created without an integer.
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.
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 the parameter to m_member, if the member is a constant object or reference is the same. According to the C ++ rules, constant objects and references cannot be assigned values. They can only be initialized.

The second reason is that for efficiency consideration, when the member class has a default constructor and a value assignment operator. The cstring of MFC provides a perfect example. Assume that you have a cmyclass member m_str of the cstring type, and you want to initialize it as "yada .". You have two options:
Cmyclass: cmyclass (){
// Use the value assignment operator
// Cstring: Operator = (lpctstr );
M_str = _ T ("yada ");
}
// Use the class member list
// And constructor cstring: cstring (lpctstr)
Cmyclass: cmyclass (): m_str (_ T ("yada "))
{
}
Are there any differences between them? Yes. The compiler always ensures that all member objects are initialized before the constructor is executed. Therefore, the Code compiled in the first example calls cstring: cstring to initialize m_str, this is completed before the control reaches the value assignment statement. In the second example, the compiler generates a call to cstring: cstring (lpctstr) and passes "yada" to this function. The result is that two cstring functions (constructor and value assignment operator) are called in the first example, and only one function is called in the second example. In the cstring example, this does not matter, because the default constructor is inline. cstring only allocates memory for the string as needed (that is, when you actually assign values ). However, in general,
Repeated function calls are a waste of resources, especially when constructors and value assignment operators allocate memory. In some large classes, you may have a constructor and an assignment operator that calls the init function with the same responsibility for allocating a large amount of memory space. In this case, you must use the initialization list to avoid unnecessary memory allocation twice. There is no performance difference between the initialization list and the assignment in the constructor body for internal types such as ints, longs, or other types without constructors. No matter which method is used, only one value assignment occurs. Some programmers say that you should always use the initial list to maintain good habits, but I have never found any difficulty in converting the two methods as needed. In programming style, I tend to use assignment in the subject, because there is more space for formatting and
To add a comment, you can write the following statement: x = y = z = 0;
Or memset (this, 0, sizeof (this ));
Note that the second part is definitely not object-oriented.
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 may think that the above Code will first do m_y = I, then m_x = m_y, and finally they have the same value. But the compiler first initializes m_x and then m_y, because they are declared in this order. The result is m_x, which will have an unpredictable value. My example is designed to illustrate this point. However, this bug will occur more naturally. There are two ways to avoid it. One is to declare members in the order you want them to be initialized, and the other is, if you decide to use the initialization list, these members are always listed in the order they are declared. This will help eliminate confusion.

2. Many people are confused about initialization in constructor. The initialization after the colon is not too explicit, and the difference between them is always unclear, I want to discuss my understanding and opinions on this issue with you.
In the program, variables are defined and initialized in two forms: one is our traditional initialization form, that is, the value assignment operator, and the other is the brackets assignment, such:
Int A = 10;
Char B = 'R'; \ value assignment operator
Int A (10 );\
Char B ('R'); \ brackets assign values
The above definition and initialization form are correct and can be compiled, but the value assignment in parentheses can only be defined and initialized, and cannot be used after the definition of variables, this is different from the value assignment operator, for example:
(1)
Int A; \\define a variable first
......
A = 10; \ assign values as needed

(2)
Int B; \\define a variable first
......
B (10); \\and (1) are assigned as needed
(1) It can be compiled to define a variable A but it is not initialized. When variable A is required, 10 is assigned to a through the value assignment operator, and in (2) in, 10 is assigned to B through parentheses, but the compilation system considers
This is a function call. The name of the function is B and 10 is the actual parameter. Therefore, the compilation is incorrect. Therefore, the value assignment in parentheses is only used to define variables and initialize them.


Now let's look at the problems of colon initialization and function initialization in constructor. Class constructor is used to call a class object to construct the data members of this class object when creating a class object, first, we need to allocate memory space for this data member. Second, we need to initialize the function data member and construct the data member in the Order stated by the data member in the class.

The difference between colon initialization and function body Initialization is:
The colon (:) Initialization is performed when a data member is allocated memory space. That is to say, if a data member is assigned a value expression after the colon (this expression must be a value expression in parentheses ), after the memory space is allocated, the data member is assigned a value before entering the function body, that is, the data member is initialized and the function body has not yet been executed.
Initialization in a function is performed only after all data members are allocated memory space.
This is advantageous. Some data members need to initialize the function body before calling the constructor, such as referencing data members, constant data members, and object data members, take a look at the following program:
Class student
{

Public:
Student ()
...
Protected:
Const int;
Int & B;

}

Student: Student (int I, Int J)
{
A = I;
B = J;
}

The student class has two data members: one is a constant data member, the other is a reference data member, and the two data members are initialized in the constructor, but this cannot be compiled, because a constant value must be assigned during initialization, and its value cannot be changed. Like a constant, a value must be assigned for initialization. After a reference is defined, it is associated with the referenced object and cannot be assigned a value. So C
+ + ":" The post-initialization mechanism makes reference and constant data members possible. The student class constructor should be:
Student: Student (int I, Int J): A (I), B (j ){}

In the following program:
Class teach
{
Public:
Teach (char * P = "name", int A = 0)
...
Protected:
Char name [30];
Int age;
}
Teach: Teach (char * P, int)
{
Strcopy (name, P );
Age =;
Cout> Name> Endl;
}
Class student
{
Public:
Student (char * P = "name ");
...
Protected;
Char name [30];
Teach teacher;
};
Student: Student (char * P)
{
Strcopy (name, P );
Cont> Name> Endl;
}
In the above program, the compilation system will tell you that the default constructor is missing for the teacher Class Object, because the default constructor is not defined in the teach class. How can a constructor with parameters be constructed? Assign values using the colon as mentioned above. The constructor should be:

Student: Student (char * P, char * PL, int AG): Teacher (PL, AG)
{
Strcopy (name, P );
Cont> Name> Endl;
}

Protected;
Char name [30];
Teach teacher
Class Object cannot contain parameters because it is only declared.

Therefore, this mechanism is added in C ++, which is required for object-oriented programming. I don't know. If you do not understand, please refer to the relevant information.

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.