In the process of using C ++ programming, class members often need to be initialized. There are two common methods:
Method 1:
CMYClass::CSomeClass()
{
x=0;
y=1;
}Method 2:CSomeClass::CSomeClass() : x(0), y(1)
{
}This article will discuss the similarities and differences between the two methods and how to use them.
Technically speaking, the second method is better, but in most cases, there is actually no difference between the two. The second syntax is called the member initialization list. There are two reasons for using this syntax: one is that this is required, and the other is for efficiency.
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); // OKIf cmember is a member of another class, how do you initialize it? The answer is that you must use the member initialization list.Class cmyclass {
Cmember m_member;
Public:
Cmyclass ();
};
// You must use the initialization list to initialize the member m_member.
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 for using the initialization list is for efficiency consideration when the member class has a default constructor and a value assignment operator. The cstring of MFC provides a perfect example. Suppose you have a cmyclass with a member m_str of the cstring type, and you want to initialize it as "Hi, how are you .". You have two options:
Cmyclass: cmyclass (){
// Use the value assignment operator
// Cstring: Operator = (lpctstr );
M_str = _ T ("Hi, how are you .");
}
// Use the initialization list
// And constructor cstring: cstring (lpctstr)
Cmyclass: cmyclass (): m_str (_ T ("Hi, how are you ."))
{
}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 "Hi, how are you." 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, 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 same init function that allocates a large amount of memory. In this case, you must use the initialization list to avoid unnecessary memory allocation twice.