The syntax of subclass constructors in C + + inheritance

Source: Internet
Author: User

Reproduced in: http://www.cnblogs.com/kaige/p/cplusplus_virtual_inheritance_derived_class_constructor.html

The constructor method is used to initialize the object of the class, unlike the other members of the parent class, which cannot inherit from the child class (the subclass can inherit all the member variables and member methods of the parent class, but not the parent class's constructor method). Therefore, when creating a subclass object, the system needs to invoke the constructor of its parent class in order to initialize the data members inherited from the parent class.

Without an explicit constructor, the compiler gives a default constructor, and the default constructor is created only if the constructor is not explicitly declared.

The construction principles are as follows:

1. If the subclass does not have a constructor method defined, call the constructor of the parent class without arguments.

2. If a subclass defines a construction method, whether it is a parameterless or a parameter, when the object of the subclass is created, it first executes the parent class parameterless constructor, and then executes its own construction method.

3. When creating a subclass object, the default parameterless constructor of the parent class is called if the constructor of the subclass does not display the constructor that invokes the parent class.

4. When a subclass object is created, the parent class's own parameterless constructor is called if the constructor for the subclass does not display the constructor that invokes the parent class and the parent class provides itself with a parameterless constructor.

5. When creating a subclass object, if the constructor of the subclass does not show the constructor of the calling parent class and the parent class only defines its own parameter constructor, an error occurs (if the parent class has only a constructor that has parameters, the subclass must display the call to this parameter constructor).

6. If a subclass invokes a constructor with a parent class with arguments, it needs to initialize the parent class member object in such a way that:

1#include <iostream.h>2 3     classAnimal4 {5      Public:6AnimalintHeightintweight)7 {8cout<<"Animal Construct"<<Endl;9 }Ten ... .. One }; A  -     classFish PublicAnimal - { the      Public: -Fish (): Animal ( -, -) - { -cout<<"Fish Construct"<<Endl; + } - ... .. + }; A     voidMain () at { - Fish fh; -}

After the fish class's constructor, add a colon (:), and then add the parent class's constructor with parameters. Thus, when the constructor of a subclass is called, the system invokes the constructor of the parent class with parameters to construct the object. This initialization is also often used to initialize constant (const) members in a class, as shown in the following code:

1 class Point2 {3      Public:4Point (): X (0), Y (0)5     Private:6        Const intx;7        Const inty;8};

Of course, ordinary member variables in a class can also be initialized in this way, however, this is not necessary.

The recent work of a software feature has been degraded, traced down to find that a class member variable is not properly initialized. This problem is related to the syntax of a derived class constructor in the case of a virtual inheritance of C + +. Here is a description of the cause of the error, hoping to help more people.

The inheritance structure of the classes with virtual inheritance in our code is not the same as the classic diamond structure in the textbook. Inheritance from Intermediate1 and Intermediate3 to Base2 is virtual inheritance. Base1 and Base2 contain some member variables and provide the appropriate constructors to accept the specified initialization values. BASE2 also has a default constructor that initializes its member variables to 0. intermediate1,2,3 also provides a constructor that takes the specified initialization value and calls Base1 and Base2 constructors in the initialization list to complete the initialization.

When a colleague is refactoring, he accidentally changes the final code to:

1 classFinal: PublicIntermediate2, PublicIntermediate3 {2  Public:3Final (intAintBintc)4 : Intermediate2 (A, B, c),5 Intermediate3 (b, c)6     {7  8     }9  Ten};
1 classIntermediate1: PublicBASE1,Virtual  PublicBase2 {2  Public:3Intermediate1 (intAintBintc)4 : Base1 (a),5 Base2 (b, c)6     {7  8     }9 };Ten   One classIntermediate2: PublicIntermediate1 { A  Public: -Intermediate2 (intAintBintc) - : Intermediate1 (A, B, c), the Base2 (b, c) -     { -   -     } + }; -   + classIntermediate3:Virtual  PublicBase2 { A  Public: atIntermediate3 (intBintc) - : Base2 (b, c) -     { -   -     } -};

It appears that the final constructor will call the constructors of Intermediate2 and Intermediate3 to initialize M_a, M_b, and M_c, respectively, to the specified value. However, the runtime discovers that the value of M_b and M_c is 0! Obviously, this is the default constructor that calls the Base2.

It turns out that the rule of C + + is that if there is a base class for virtual inheritance on the inheritance chain, the bottommost subclass is responsible for completing the construction of the partial members of the virtual base class. we can explicitly call the virtual base class constructor to complete the initialization. If you do not explicitly call the virtual base class's constructor, the compiler calls the virtual base class's default constructor. If the constructor of the virtual base class is not explicitly called, and the virtual base class does not have a default constructor defined, a compilation error occurs. The reason for this rule is that if you do not do this, the virtual base class part will be initialized more than once on multiple inheritance chains that exist.

Many times, for intermediate classes on an inheritance chain, we also explicitly invoke the constructor of the virtual base class in its constructor, because once someone wants to create objects of those intermediate classes, we also want to ensure that they are properly initialized.

So, if we're going to initialize M_b and M_c to the specified value, the final constructor should be the correct way to do this:

1 Final (intintint  c)2    : Base2 (b, c),3       Intermediate2 (A, B, c),4      Intermediate3 (b, c)5{ 6  7 }

The complete test program is shown below, and interested students can compile and run them on their own. You can also step through the final constructor in the debugger to see which of the two Base2 's constructors were called.

1#include"stdafx.h"2#include <iostream>3  4 using namespacestd;5  6 classBase1 {7  Public:8BASE1 (inta): M_a (a) {}9  Ten protected: One     intm_a; A }; -   - classBase2 { the  Public: -Base2 (intBintc): M_b (b), M_c (c) {} -Base2 (): M_b (0), M_c (0) {} -   + protected: -     intM_b; +     intM_c; A }; at   - classIntermediate1: PublicBASE1,Virtual  PublicBase2 { -  Public: -Intermediate1 (intAintBintc) - : Base1 (a), - Base2 (b, c) in     { -   to     } + }; -   the classIntermediate2: PublicIntermediate1 { *  Public: $Intermediate2 (intAintBintc)Panax Notoginseng : Intermediate1 (A, B, c), - Base2 (b, c) the     { +   A     } the }; +   - classIntermediate3:Virtual  PublicBase2 { $  Public: $Intermediate3 (intBintc) - : Base2 (b, c) -     { the   -     }Wuyi }; the   - classFinal: PublicIntermediate2, PublicIntermediate3 { Wu  Public: -Final (intAintBintc) About : Base2 (b, c), $ Intermediate2 (A, B, c), - Intermediate3 (b, c) -     { -   A     } +   the     voidPrint () { -cout<<m_a<<", "<<m_b<<", "<<m_c<<Endl; $     } the }; the   the   the int_tmain (intARGC, _tchar*argv[]) - { inFinal Finalobj (1,2,3); the finalobj.print (); the   About     return 0; the}

The syntax of subclass constructors in C + + inheritance

Related Article

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.