About initializing C ++ class members

xiaoxiao2021-03-06  40

http://www.vckbase.com/document/viewdoc/?id=584

In the process of using C programming, it is often necessary to initialize class members, and there are two types:

the first method:

CMYCLASS :: CsomeClass ()

{

X = 0;

Y = 1;

}The second method:

CsomeClass :: csomeclass (): x (0), y (1)

{

} This article will explore the difference between these two methods and how to use these two methods.

As a result, the second method is better, but in most cases, the two actually have no difference. The second grammar is called a member initialization list, and there are two reasons why it is necessary to use this syntax: one reason is to do, and the other is for efficiency considerations. Let's take a look at the first reason - the need. Imagine that you have a class member, it itself is a class or structure, and there is only one constructor with a parameter.

Class cmember {

PUBLIC:

Cmember (int x) {...}

}; Because cmember has an explicit declared constructor, the compiler does not produce a default constructor (without parameters), 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? The answer is that you must use a list of members to initialize.

Class CMYCLASS {

Cmember m_member;

PUBLIC:

CMYCLASS ();

}

/ / The list of initializes must be used to initialize Members M_Member

CMYCLASS :: CMYCLASS (): m_member (2)

{

•••••

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

The second reason for using the initialization list is for efficiency, when the member class has a default constructor and an assignment operator. The MFC's CString provides a perfect example. Assume that you have a class CMYClass member M_STR, you want to initialize it to "Hi, How are you.". You have two options:

CMYCLASS :: CMYCLASS () {

// Use assignment operators

// cstring :: Operator = (lpctstr);

m_str = _t ("hi, how are you.");

}

// use initialization list

// and constructor cstring :: cstring (lpctstr)

CMYCLASS :: CMYCLASS (): m_str (_T ("Hi, How are you."))

{

} Is there something difference between them? Yes it is. The compiler always ensures that all member objects are initialized before the constructor is executed, so the code compiled in the first example will call CString :: CString to initialize M_STR, which is completed before the control arrives. In the second example, the compiler generates a call to CString :: CString (LPCTSTSTR) and passes "Hi, How Are you." To this function. The result is that two CSTRING functions (constructor and assignment operators) are called in the first example, and only one function is called in the second example.

This doesn't matter in the case of CString, because the default constructor is inline, CSTRING is only assigned memory as a string when needed (ie, when you actually assign). However, in general, the repetitive function call is a waste of resources, especially when constructor and assignment operators allocate memory. In some big classes, you may have a constructor and an assignment operator to call the same init function responsible for allocating a large amount of memory space. In this case, you must use an initialization list to avoid not allocating two memory. Under the types such as INTS or LONGS, or other in the type without constructor, there is no difference in the initialization list and the two methods assigned to the constructor. Regardless of the way, only one assignment will occur. Some programmers say that you should always use the initial list to maintain a good habit, but I have never found that there is difficulty in converting the two methods. In the programming style, I tend to use assignment in the body, because more space is used to format and add a comment, you can write this statement: x = y = z = 0; or

MEMSET (this); Note The second piece is definitely non-objective.

When I consider the problem of initialization list, there is a strange feature that I should warn you, it is a member of the C initialization class, which is initialized in the order of statements, rather than in the order in the initialization list.

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. However, the compiler first initializes M_x, then M_Y, because they are in this order. The result is that M_x will have an unpredictable value. This example is intentionally designed to illustrate this, however this BUG will appear naturally. There are two ways to avoid it, one is to declare members in order you want them to be initialized, and the second is that if you decide to use the list of initialization, you always follow these members in order to declare the order. This will help eliminate confusion.

转载请注明原文地址:https://www.9cbs.com/read-57327.html

New Post(0)