Is a new C ++ 11 member initialization function included when announcing that initialization lists are out of date?

With C ++ 11, we now have the ability to initialize class members in the header declaration:

class aClass { private: int mInt{100}; public: aClass(); ~aClass(); }; 

So, I'm a little confused. Traditionally, initialization lists in constructors have been used to initialize a member:

 aClass::aClass() : mInt(100) { ... } 

Did the new C ++ 11 member initialization function work when announcing that the initialization lists are out of date? If not, what are the advantages of one over the other? In what situations is initialization beneficial when declaring, or are initialization lists beneficial? When to use each other?

+48
c ++ constructor initialization c ++ 11 declaration
Jun 10 '14 at 20:04
source share
3 answers

No, they are not outdated, as in this article Check out the new C ++ 11 initialization formats in the initialization section of a class member (my attention):

Keep in mind that if the same data element has both a class member initializer and mem-init in the constructor, the latter takes precedence. In fact, you can take advantage of this behavior by specifying a default value for the member in the form of the initializer of the class member that will be used if the constructor does not have an explicit mem-init for this member. Otherwise, the mem-init constructor will take effect by overriding the initializer of the class member. This method is useful in classes with multiple constructors.

Thus, although initializing a class member is very convenient, it does not eliminate the need for initialization lists, but both functions work together to give you a good way to specify default values โ€‹โ€‹and override them when necessary. This is similar to how Bjarne Stroustrup sees it, he says:

This saves a bit of input, but the real benefits come in classes with multiple constructors. Often, for all constructors, a regular member initializer is used:

and provides an example of elements that share a common initializer:

 class A { public: A(): a(7), b(5), hash_algorithm("MD5"), s("Constructor run") {} A(int a_val) : a(a_val), b(5), hash_algorithm("MD5"), s("Constructor run") {} A(D d) : a(7), b(g(d)), hash_algorithm("MD5"), s("Constructor run") {} int a, b; private: HashingFunction hash_algorithm; // Cryptographic hash to be applied to all A instances std::string s; // String indicating state in object lifecycle }; 

and says:

The fact that hash_algorithm and s each has one default is lost in a mess of code and can easily become a problem during maintenance. Instead, we can eliminate the initialization of data members:

 class A { public: A(): a(7), b(5) {} A(int a_val) : a(a_val), b(5) {} A(D d) : a(7), b(g(d)) {} int a, b; private: HashingFunction hash_algorithm{"MD5"}; // Cryptographic hash to be applied to all A instances std::string s{"Constructor run"}; // String indicating state in object lifecycle }; 

Note: flaw in C ++ 11

There is one drawback of using a class member in initialization in C ++ 11, since it makes the class non-aggregate, we can no longer use aggregate initialization , which can be quite unexpected. This does not apply to C ++ 14, where this restriction has been removed. See Initializing C ++ 11 aggregates for classes with non-stationary element initializers for more details.

+50
Jun 10 '14 at 20:18
source share

No, they are not outdated.

Initialization lists are still the only way if you need constructor arguments to initialize your class members.

 class A { int a=7; //fine, give a default value public: A(); }; class B { int b; public: B(int arg) : b(arg) {} B(int arg, bool b) : b(arg) { ... } }; 

Note that if both are present, the constructor initializer will take effect by overriding the initialization of the class member, which is useful for specifying the default value for the class member.

+6
Jun 10 '14 at 20:16
source share

As I look at this, initialization in a class is a representation of mem-initializer lists. In C ++ 03, members not listed in the mem-initializer list were always initialized by default. This means the default constructor for classes and initialization for primitive types.

Class initialization simply allows you to specify your own default values. There are two ways to look at this.

One: if most / all the constructors of your class want to provide the same initial value for the member, use the initializer in the class for this element. For other members, use the mem-initializer list. Of course, you should use them when the initial value depends on the arguments of the constructor.

Another: provide an initializer in the class for all members, exactly how their default constructor initializes your class. Then, the mem-initializer lists in non-default constructors get the semantics โ€œhow does it differ from the default objectโ€.

+5
Jun 10 '14 at 20:16
source share



All Articles