Effective C + + 43,44

Source: Internet
Author: User

43. Use multiple inheritance wisely.

Multiple inheritance brings a great deal of complexity. The most important one is the ambiguity.

When a derived class is multiple-inheritance, its multiple base classes have members with the same name, and two semantics occur. It is common to know which member to use. Explicitly restricting decorated members is not only very clumsy, but also a limitation. When a virtual function is explicitly decorated with a class name, the function is fixed and no longer has a virtual attribute. For virtual functions, if two base classes have a virtual function with the same name, when the derived class does not define the virtual function again (which can only be declared), calling the same name function directly will give a two semantic error and need to indicate its class. And when this function is defined again in a derived class, it is not possible, because a class simply agrees to have only one function with the same name (in fact, the function body sound does not declare const, or is different, one for the normal object and one for the const object). In the case of a derived class, another definition of the virtual function, in fact, in the derived class once again created a function, where it is not necessary to define two virtual functions again, because the redefinition of a function is to create a function, and a function can not have two of the same name function.

When the virtual function is not altered, it is only necessary to call the function of the base class in the way of the specified base class, when it is necessary to define a virtual function again, that is, when the derived class only retains a virtual function, it does not care about which virtual function it retains, just the normal declaration of the definition again.

When it is necessary to define multiple virtual functions again, and when the derived classes use these virtual functions, a so-called ingenious method solves the two semantics, which is to derive under the two base classes of the existence of ambiguity, to define their new names in the two derived classes, and the function body to call the function of the base class inline. And the multiple inheritance of the derived class of multiple inheritance and the two intermediate classes, the two originally conflicting base class functions into two non-conflicting base class functions. Instead of defining a virtual function again, you have to introduce a new class.

Class a{public:virtual void Fun () {cout<< "A" <<endl;}}; Class b{public:virtual void Fun () {cout<< "B" <<endl;}}; Class auxa:public a{public:virtual void Afun () = 0;virtual void Fun () {return afun ();}}; Class auxb:public b{public:virtual void Bfun () = 0;virtual void Fun () {return bfun ();}}; Class C:public auxa,public auxb{public:virtual void Afun () {cout<< "A in C" <<ENDL;} virtual void Bfun () {cout<< "B in C" <<endl;}}; Class D:public A,public B{};int main () {d* d = new D ();//For normal conditions, a * AAA =d;//when it uses the base class pointer, Aaa->fun ();//Will call the base class's virtual function, Without conflict b* BBB = d;//completely did not manifest to polymorphic bbb->fun ();//d->fun ();//and direct invocation would be ambiguous. c* c =new C ();//c->fun ();//Renaming the original function is still two semantic. A * AA = C;aa->fun ();//output A in cb* bb = c;//output B in Cbb->fun (); Auxa *a = c; AUXB * b = c;a->fun ();//Output A in Cb->fun ();//output B in C
This is the same as renaming a function with the same name in a derived class that defines two base classes again.


In addition to the ambiguity, the problem that is often encountered is the diamond inheritance, that is, a base class is inherited multiple times, it is possible to save multiple copies of the problem. In general, there is only one such base class that is declared as a virtual base class.

But this is also problematic, the first program developed this design a base class A derived from a number of base class, BC, but in its definition of BC can not know later whether someone will inherit more BC, and then want to change the definition of BC to make its virtual inherit from Class A is very difficult to do, general ABC is just read library function, And D is developed by the user of the library. On the other hand, suppose that a declares to be the virtual base class of BC, which in most cases brings additional space and time consumption to the user.

For virtual base classes, if a is a non-virtual base class, the allocation of D objects in memory usually occupies contiguous memory units, and if a is a virtual base class, a pointer to a function unit that points to the virtual base class data member is included. Here for a derivation BC, whereas D inherits from B and C, D has two a in memory, but assumes a virtual base class, and D has two pointers to a.

So consider these, for efficient class design, when it comes to mi multi-inheritance, as the library designers will have extraordinary foresight.

Passes the constructor parameters to the virtual base class. For single inheritance, derived classes pass a reference to the base class in the member initialization list, because they are single-inheritance, and these parameters can be passed up and down the level. However, the constructor of the virtual base class is different, and its parameters are specified by the member initialization list of the lowest-level derived class in the inheritance structure, assuming that a new class is added to the inheritance structure, and the class that runs the initialization may have to be modified. The way to avoid this problem is to eliminate the need for the virtual base class to pass the constructor parameters, the simplest is the Java solution, that is, to avoid putting data members in the virtual base class, the virtual base class interface in Java is forbidden to include data.

The priority of the virtual function. When virtual function in multiple inheritance involves virtual base class, there will be a priority problem, still take ABCD as an example, there is a virtual function void fun (), C in the definition of fun, but B and D do not, call D's pointer fun, if a is not a virtual base class, it is normal situation, a two semantic error occurs. However, when a is a virtual base class, it can be said that the priority of the re-defined fun in C is higher than the first definition of a is also the fun in B, then there will be no ambiguity resolution to call the C::fun () function.

When the original Class B inherits from Class A, now it is necessary to add a new Class C inheritance with a, but you find it with the Class B with a lot of similarities, but C is not a B, so you decided to let C by B, let C private inheritance in B, the same time inherit a, the same time changed the virtual function in B, the implementation of multiple inheritance. Another way is to put the common denominator of BC in a new Class D, change the inheritance structure, so that D inherits from a, and BC inherits from D, so that there is only single inheritance. On the surface, multiple inheritance does not add a new class, does not change the original inheritance structure, it is only in the original class B based on the addition of some new virtual functions, it seems to add a lot of functionality, and just add a little bit of complexity. But the fact that the introduction of multiple inheritance will bring a lot of trouble.

Mi is complex, but also practical, and needs to be used wisely.


44. Say what you want to say and understand what you want to say.

In simple terms, understanding the meaning of object-oriented artifacts in C + + is not just about remembering the C + + language rules. The deeper you understand C + +, the more clearly you can consider the problem.

Effective C + + 43,44

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.