Article 40: Judicious and prudent use of multiple inheritance

Source: Internet
Author: User

    Multiple inheritance (multiple Inheritance:mi) has different propositions in the C + + camp. One is: If single inheritance is considered good, then multiple inheritance must be good, and the other is: Single inheritance is good, but multiple inheritance is not. Inheritance:si These two views are mainly understood in this article.

    When using MI, the program may inherit the same name (function, typedef, etc.) from more than one base classes, which can lead to ambiguity (ambiguity)

        clas BorrowableItem{    public:        voidcheckOut();        ……    };    class ElectronicGadgent{    private:        boolcheckOutconst;        ……    };    publicpublic ElectronicGadget    {        ……    };    MP3Player mp;    mp.checkOut();//歧义,调用哪个checkOut

    Note that although the above two functions are public and one is private, there is still ambiguity. This is consistent with the rule that C + + uses to parse (resolving) overloaded function calls: C + + first confirms that this function is the best match for this call before seeing if a function is available. The above two checkOut have the same matching degree. To resolve ambiguity, you must indicate which function in the base class is called

    mp.BorrowableItem::checkOut();

    Of course you can call Electronicgadget::checkout, but you'll get an "attempt to call Private member function" error.

    Multiple inheritance may also cause "diamond inheritance"

    classFile{……};    classpublicFile{……};    classpublicFile{……};    class IOFile:publicpublic OutputFile    {……};

    In the above inheritance system, Iofile will have two copies of file, because both Inputfile and outfile have a copy, and Iofile has these two class copies. If the file class has a member variable filename, then there are two such data in the Iofile. Iofile inherits base classes, so there should be two copies, but the two variables are duplicates, and filename needs only one copy.

    C + + has no position in the debate on whether 2 copies are required, two of which are supported, and the default is the first scenario. If you want to use the second scenario, then let the class with this data (that is, file) become a virtual base class.

        classFile{……};    classvirtualpublicFile{……};    class OutputFile:virtualpublicFile{……};    class IOFile:publicpublic OutputFile    {……};

    The C + + standard library has a multiple inheritance system, which is a class templates. The names were Basic_ios,basic_istream,basic_ostream and Basic_iostream.

    From the above example, it seems that the public inheritance should be virtual. But this view is not correct. In order to avoid duplication of member variables, the compiler paid a price, using virtual inheritance of objects larger than non-virtual inherited objects, access to the virtual base classes member variable is, also than access to non-virtual base Classes member variable speed is slow. You can refer to this

    Virtual inheritance costs also include virtual base classes initialization. Virtual base initialization has the lowest (most derived) class in the inheritance system. This means (1) that classes derived from virtual bases needs to be initialized and must be aware of its virtual bases; (2) When a new derived class is added to the inheritance system, it must assume responsibility for the initialization of virtual bases (direct or indirect).

    The advice to virtual inheritance is: (1) When unnecessary, do not use virtual inheritance, usually using non-virtual inheritance. (2) If you have to use virtual inheritance, try to avoid putting the data in base so you don't have to worry about the classes of initialization and assignment. Java and. NET interfaces are in many ways compatible with C + + 's virtual base classes, which does not allow any data.

    Now look at the * * Clause **31 interface class used to shape people

        class IPerson{    public:        virtual ~IPerson();        virtualstd::stringconst=0;        virtualstd::stringconst=0;    };

    Customers use IPerson's pointer or reference to program because abstract classes cannot be instantiated. When creating objects, IPerson customers can use factory function (factory functions) to instantiate classes that derive from IPerson.

        //根据ID创建一个Person对象    std::tr1::shared_ptr<IPerson> makePerson(DatabaseID personIdentifier);    //从使用者手上取得一个数据库的ID    askUserForDatabaseID();    id(askUserForDatabaseID());    std::tr1::shared_ptr<IPerson> pp(makePerson(id));

    Assuming that the specific class created by Makeperson is CPerson, then CPerson must provide the pure virtual function implementation code that inherits from IPerson. Suppose there is also a database-related class PersonInfo that provides some of the things CPerson needs

    Class personinfo{ Public:Explicit PersonInfo(DatabaseID pid);Virtual~personinfo ();Virtual Const Char* Thename ()Const;Virtual Const Char* Thebirthdaydate ()Const; ......Private:Virtual Const Char*Valuedelimopen()Const;Virtual Const Char* Valuedelimclose ()Const; ...... };

    For us This is good news, we can use some of Personinfo's interface to complete the design, but there are two functions do not meet the requirements, valueDelimOpen() and valueDelimClose() , the two functions return "[" and "]", affecting the other functions, to be redefined.

    This can get CPerson and personinfo relationship is personinfo just have a number of functions can help cperson easier to implement. Their relationship is is-implemented-in-terms-of (implemented according to something), which can be implemented by two technologies: composite and private inheritance. * * Article **39 mentions that compositing is more popular, but if you want to redefine the virtual function, you must inherit it. In this case, the function cannot be redefined, so the composition cannot be used.

    CPerson also implements the IPerson interface, so the public inherits it. This results in multiple inheritance

    Class iperson{ Public:Virtual~IPerson();VirtualSTD::stringName ()Const=0;VirtualSTD::stringBirthDate ()Const=0;    };    Class databaseid{...}; Class personinfo{ Public:Explicit PersonInfo(DatabaseID pid);Virtual~personinfo ();Virtual Const Char* Thename ()Const;Virtual Const Char* Thebirthdaydate ()Const; ......Private:Virtual Const Char*Valuedelimopen()Const;Virtual Const Char* Valuedelimclose ()Const;    ...... }; Class CPerson: PublicIPerson,Privatepersoninfo{ Public:Explicit CPerson(DatabaseID pid):PersonInfo(PID) {}VirtualSTD::stringName ()Const{returnPersoninfo::thename (); }VirtualSTD::stringBirthDate () {returnPersoninfo::thebirthdate (); }Private:Const Char*Valuedelimopen()Const{return "";}Const Char* Valuedelimclose ()Const{return "";} };

    This example tells us that multiple inheritance has also its rational use.

    Multiple inheritance is just an object-oriented tool. Compared with a single inheritance, it is more complex and difficult to understand, so if there is a single inheritance scheme and a multiple-inheritance scheme, then the single-inheritance scheme is more popular. But if you can accomplish a task through multiple inheritance, and the simplest, most maintainable, and reasonable, then don't be afraid to use it.

    Summarize

      • Multiple inheritance is more complex than single inheritance. It can lead to new ambiguity and the need for virtual inheritance.
      • Virtual inheritance increases the cost of object size, speed, initialization, and assignment. If virtual base class does not have any data, it will be the most useful use case.
      • Multiple inheritance does have a legitimate purpose. One of the plot design public inherits a class that interface class and private inherit some assistance implementation.

    Article 40: Judicious and prudent use of multiple inheritance

    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.