// Meanings of multiple inheritance and solutions // objective: to understand the inheritance principle of classes and Solutions of multiple inheritance. /* // The source of the code of this program is "MFC authoritative analysis" p68 * // The first multi-Inheritance // class Employee {public: char Name [40]; bool Sex ;}; class Worker: public Employee {}; class Manager: public Employee {}; class Engineer: public Worker, public Manager {}; // The Engineer's instantiated object memory contains two Employee sub-objects, which respectively belong to the Worker and Manager sub-objects. // This encapsulates two sets of Employee profiles in the instance, it is obviously wrong. {Engineer eng; eng. worker: Sex = true; eng. manager: Sex = false; // eng gender even if male is female} // solution /////// //////////////// when the parent class has both parents, you can use the virtual base class. // The role of the virtual base class is: if there are two identical virtual base classes in the inheritance structure of a derived class, // The instantiated object of this class has only one sub-object of the virtual base class in the memory. // Example class Employee {public: char Name [40]; bool Sex ;}; class Worker: public virtual Employee // Employee {}; class Manager: public virtual Employee // Employee {}; class Engineer: public Worker, public Manager {}; // This inheritance method means that the sub-objects of the virtual base class are no longer included in each parent class, but exists independently. // A pointer to its virtual parent sub-object exists in the parent class object. This pointer is called a virtual parent class pointer and is generated by the compiler. In this way, only one sub-object of the virtual base class exists in the subclass instance during multi-inheritance. // Sub-objects of non-virtual base classes with the same name are not merged. //// // The second type of multi-Inheritance /////////// //// class ParentA {public: void fun () {printf ("% d \ n", m_Value) ;}; private: int m_Value ;}; class ParentB {public: void fun () {printf ("% d \ n", m_Value) ;}; private: int m_Value ;}; class Son: public ParentA, public ParentB {}; /////////////// ///////// when the parent class does not have a common parent, generally, the name conflict member is redefined in the subclass to solve the ambiguity. ///// // Precautions when using the virtual base class /// //// // [html] # include "stdio. h "class Base {public: Base () {printf (" Base is constructed as default \ n ");} Base (int I) {m_iValue = I; printf ("Base is constructed in constructing list \ n ");}~ Base () {printf ("Base is deconstructed \ n");} int GetiValue () const {return m_iValue;} private: int m_iValue;}; class ParentA: public virtual Base {public: ParentA () {} ParentA (int I, float f): Base (I) {m_fValue = f;} float GetfValue () const {return m_fValue ;} private: float m_fValue;}; class ParentB: public virtual Base {public: ParentB () {} ParentB (int I, char c): Base (I) {m_cValue = c ;} char GetcVa Lue () const {return m_cValue;} private: char m_cValue;}; class Son: public ParentA, public ParentB {public: Son (int I, float f, char c ): parentA (I, f), ParentB (I, c) {} void Output () {printf ("son member is % d % 8.2f % c \ n", GetiValue (), getfValue (), GetcValue () ;}; int main (int argc, char * argv []) {Son son (6, 92.33, 'D'); son. output (); return 0;}/* Output Base is constructed as default son member is-8589 93460 92.33 D ase is deconstructed * // The program output shows that the virtual base class is constructed only once and destroyed once, so only one subobject exists. // However, the Base class is called the default constructor. ParentA and ParentB are invalid for the virtual Base class. // In fact, to ensure that the virtual base class is constructed only once, the constructor of the virtual base class cannot be called in the traditional way, // that is, it cannot be called directly by subclass, instead, it is called by the constructors of the current bottommost hierarchical class, which is called the most derived class. // The truth is actually very simple. It works the same as a virtual function. // If you change the Son constructor to: Son (int I, float f, char c): ParentA (I, f), ParentB (I, c), Base (I) {}/*, the output Base is constructed as default son member is 6 92.33 D ase is deconstructed * // although the application virtual Base class solves the problem of repeated Base class sub-objects, however, the possibility of ambiguity cannot be completely eliminated. // If two direct parent Classes define functions with the same name at the same time, the two classes will also produce ambiguity.