Effective C + + 43,44

Source: Internet
Author: User

43. Use multiple inheritance wisely.

Multiple inheritance brings a great deal of complexity. The most basic 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 specify which member to use. Explicitly restricting decorated members is not only awkward, but it can also impose limitations. 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 as the same parameter, when the derived class does not redefine the virtual function (which can only be declared), calling the function directly with the same name gives a two semantic error and needs to indicate its class. When this function is redefined in a derived class, this is not possible because a class only allows a function with the same name as the same parameter (in fact, the function body sound does not declare const, or is different, one for the normal object and one for the const object). Instead of redefining a virtual function in a derived class, you re-create a function in a derived class, where it is not possible to redefine two virtual functions, because redefining a function is creating a function, and a function cannot have two functions with the same parameter.

When the virtual function is not modified, simply call the function of the base class in a way that indicates the base class, and when a virtual function needs to be redefined, that is, when a virtual function is reserved for a derived class, you do not have to care about which virtual function it retains, as long as the definition is properly re-declared.

And when you need to redefine multiple virtual functions, and the derived class to use these virtual functions, a so-called ingenious method to solve the two semantics, that is, in the existence of the ambiguity of the two base class and then to derive, in these two derived classes to define their own new name, and the function body is an inline call to the base class function. 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. Just to redefine a virtual function, 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 and redefining two base classes in a derived class.


In addition to the ambiguity, the problem that is often encountered is the diamond inheritance, that is, a base class is inherited multiple times, but whether 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 the BC can not know later whether someone will inherit the BC, and then want to modify the definition of BC to make its virtual inherit from Class A is difficult to do, general ABC is read-only library functions, And D is developed by the user of the library. On the other hand, if a is declared as the virtual base class of BC, this will in most cases give the user extra space and time to consume.

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, and D inherits from B and C, then D has two a in memory, and if it is a virtual base class, there are two pointers to a in D.

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

Pass constructor arguments to the virtual base class. For single inheritance, derived classes pass parameters to the base class in the member initialization list, and because they are single-inheritance, these parameters can be passed up and down the layer. 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, and if a new class is added to the inheritance structure, the class that performs the initialization may 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 solution in Java, that is, to avoid putting data members in the virtual base class, the virtual base class interface in Java prohibits the inclusion of 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 redefined 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, you now need 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 decide to let C by B implementation, let C private inherit from B, while inheriting a, while modifying the virtual function in B, the implementation of multiple inheritance. Another approach is to place 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 only single inheritance. On the surface, multiple inheritance does not add a new class, does not change the original inheritance structure, it just on the basis of the original Class B added some new virtual functions, which seems to add a lot of functionality, but only a little more complexity. But the fact that the introduction of multiple inheritance will bring a lot of trouble.

Mi is complex, but also useful, 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.