For the C + + default constructor, I had a two-point misunderstanding :
- Class if there are no constructors defined, then the compiler (sure!) will define a composite default constructor for the class.
- The composition default constructor initializes all data members in the class.
The first misunderstanding comes from the first book I learned C + + Primer, in the book 392 pages: "The compiler automatically generates a default constructor only if a class does not have a constructor defined."
In fact, this statement is not wrong, it shows the default constructor definition of the necessary non-sufficient conditions, but to the then beginner C + + I caused some misunderstanding.
the second misunderstanding still comes from the words in primer: the default constructor for a composition initializes the member with the same rules as the variable initialization. Members that have class types are initialized by running their respective default constructors. However, this is also one-sided to me, because primer also said:"If a class contains a member of a built-in or composite type, the class should not rely on the composition's default constructor", The implication is that the synthesized default constructor does not initialize the members of a built-in or composite type.
Summed up the reason I have these misunderstandings, the first is the beginning of the knowledge system did not form, the content of the primer said there is no real understanding, the second is that primer in some degree is not really a C + + beginner can read the book, perhaps see when they feel understand, but is missing a lot of knowledge. It also shows that primer is a treasure house, often recalling that there will be new sentiment.
Let me be puzzled by the above two views, when looking at "effective C + +", clause 05 "Understand C + + default written and called which functions " in the ".... only when these functions are required (called) will they be created by the compiler. " (" These functions "refers to the compiler version of the copy constructor, assignment operators, and destructors, and also includes the default constructor.) In other words, the default constructor is " required " when the compiler will help us to synthesize, then what is the default constructor "is required"? The question "Effective C + +" did not give an answer, until we read the "Deep Exploration of the C + + object Model" to see when the compiler would help us synthesize a default constructor.
The purpose of my writing this article is to give a beginner of C + + that I have the same misunderstanding or doubt, if you have a good understanding of the composition default constructor, please ignore the contents of this article.
Body
- What is the default constructor?
The default constructor is a constructor that can be called without arguments, and it includes the following two scenarios:
- There are no constructors with explicit parameters.
- The constructor for the default argument is provided.
The Class Designer can write a default constructor by itself. The compiler helps us write the default constructor, called the composite default constructor. The reason for the "no obvious formal parameter" is that the compiler always inserts an implied this pointer for our constructor parameter list, so "essentially" is a constructor with no formal parameters, only a constructor without explicit parameters, which is the default constructor.
- When is the default constructor called?
if The default constructor is used when an object is defined without an initialization. For example:
class a{public: A (booltrueint _num=// default constructor BOOL isTrue; int num;}; int Main () { // Call the default constructor for Class A }
- Understand the three words of "being needed"
As mentioned earlier in effective C + +, the compiler will not synthesize the default constructor until the default constructor is "required". The key word is "being needed". Who needs it? As in the following code, is the default constructor "required"?
class a{public: bool isTrue; int num;}; int Main () { a A; if (a.istrue) << a.num; return 0 ;}
You might think that when you define class object A without providing a parameter and a does not define a default constructor, the compiler must have synthesized a default constructor and called it to initialize the data member of a, but it is not. When you try to view the composition default constructor to initialize the data member num to why value, you will find that the compiler even makes you unable to run the program:
When a class contains only members of a built-in type or composite type, the compiler does not synthesize the default constructor for the class, and the class does not conform to the "required" condition, even when the class satisfies the "required" condition, and the compiler synthesizes the default constructor. The built-in type and composite type data members in a class still do not initialize in the default constructor. Also mentioned in primer:"If a class contains a member of a built-in or composite type, the class should not rely on the composition's default constructor."
In the above code, the default constructor "is required" is for the program, the program needs istrue to be initialized so that the condition can be judged, it needs num to be initialized so that it can be output. This need, however, does not prompt the compiler to synthesize the default constructor. The compiler will only synthesize the default constructor when it is required by the compiler. What kind of class is the compiler need to synthesize the default constructor?
Summarize:
- The composite default constructor always does not initialize the class's built-in type and the data members of the composite type.
- Clearly the default constructor is required by the program and is required by the compiler, and only the default constructor required by the compiler will be synthesized by the compiler.
- When will the default constructor be required by the compiler?
In the following four case classes, the compiler always needs the default constructor to do some work:
1. Contains a class object data member that has a default constructor for the class object type.
If a class does not have any constructors, but it contains a class object data member, and the class object type has a default constructor, the compiler will synthesize a default constructor for that class, but this compositing operation will only occur if the constructor really needs to be called. For example, the compiler will synthesize a default constructor for Class B:
classa{ Public: A (BOOL_istrue=true,int_num = 0) {isTrue = _istrue; num = _num;};//default constructor BOOLisTrue; intnum;};classb{ Public: A;//Class A contains a default constructor intb; //...};intMain () {b b; //when compiled to this point, the compiler will compose the default constructor for B return 0;}
What does the default constructor that is synthesized do? Probably like this:
B::b () { a.a::a ();}
The default constructor that is synthesized contains only the necessary code, which completes the initialization of data member A, but does not produce any code to initialize the B::B. As mentioned above, initializing a built-in type or compound type member of a class is the responsibility of the program rather than the compiler. To meet the needs of the program, we typically write our own constructors to initialize the b::b, like this:
b::b () { // compiler inserted code 0; // display the defined code }
If there are multiple class object members in a class, the compiler inserts the code that invokes each class's default constructor sequentially in the constructor, in the order in which they are declared by these class object members.
2. The base class has a derived class with a default constructor.
When a class derives from a base class that contains a default constructor, the class also conforms to the criteria that the compiler needs to synthesize the default constructor. The default constructor for the compiler composition calls the base class default constructor of the upper layer based on the order of the base class declaration. Similarly, if a designer defines multiple constructors, the compiler will not redefine a composite default constructor, but instead insert the contents of the composition default constructor into each constructor.
3. Classes with virtual functions
Classes with virtual functions can be divided into two situations:
- The class itself defines its own virtual function
- The class inherits the virtual function from the inheritance system (once the member function is declared as a virtual function, inheritance does not change the virtual function's "virtual nature").
Both of these situations make a Class A class with virtual functions. Such a class also satisfies the class that the compiler needs to synthesize the default constructor, because the class object containing the virtual function contains a virtual table pointer vptr, and the compiler needs to set the initial value of the vptr to satisfy the virtual function, and the compiler puts the operation of the initial value in the default constructor. If the designer does not define any of the default constructors, the compiler will synthesize a default constructor to do the above, otherwise the compiler will insert code in each constructor to accomplish the same thing.
4. Classes with virtual base classes
The concept of the virtual base class exists between the class and the class, and it is a relative concept. For example, if Class A virtual inherits from Class X, then for a, Class X is the virtual base class of Class A, not to say that Class X is a virtual base class. The virtual base class is a problem that ensures that each parent class in a subclass object contains only one copy under multiple inheritance, such as Diamond inheritance. Such as:
Thus, the class a object contains a copy of the class X object, and Class C also contains a class X object, when we encounter the following code:
classX Public:inti;};classA: Public Virtualx{ Public:intJ;};classD | Public Virtualx{ Public:DoubleD;};classC: PublicA Publicb{ Public:intK;};voidfunction (A *PA) {PA->i = +;}intMain () {A*a=NewA (); C*c=NewC (); function (a); //the focus is on this .function (c);//the focus is on this . return 0;}
The true type of the function parameter PA can be changed, either by assigning a pointer to PA, or by assigning the object pointer to PA, at compile time it is not possible to determine whether the PA stored i is a or C virtual base class object. To solve this problem, the compiler produces a pointer to the virtual base class X, which allows the program to determine the actual storage location of the x::i accessed through the PA at run time. The placement of this pointer, the compiler will be in the composition of the default constructor, the same, if the designer has written a number of constructors, then the compiler will not re-write the default constructor, but instead of the virtual base class pointer placement code into the existing constructor.
To re-emphasize the beginning of the article, the following two points are misconceptions:
A) If no constructor is defined for any class, the compiler will synthesize a default constructor for us.
b) The composition default constructor initializes each data member in the class.
The compiler will not synthesize a default constructor for a class that does not have any constructors, or insert them into an existing constructor only if the compiler needs a default constructor to complete the compilation task.
The compiler requires four cases of the default constructor, which is summed up as:
A) Call the default constructor for the object member or base class.
b) Initializes the virtual table pointer with the virtual base class pointer for the object.
PS: If this article where the elaboration is unclear or wrong, very looking forward to point, thank you!
The truth about the default constructors for C + + compositing