[Herb SUTTER
Name
More Exceptional C
The Chinese version is coming soon. As a translator of this book, I am very happy to recommend this book to everyone. Judging from Huazhong University of Science and Technology Press agreed, I will disclose some translation, please ask everyone to criticize.
]
Inheritance and polymorphism
Do not inherit and polymorphism, what will be object-oriented?
Although inheritance is often abused, it is still a very important tool - this includes multiple inheritance. In particular, when you live in the real world, you will find that you often need to combine the libraries that different suppliers can use. At this time, more inheritance highlights its value. This chapter shows you that how to avoid the SIAMESE TWIN problem in combination with the "inherited" distributors provided by different suppliers. In addition, this chapter also demonstrates many ways to use pure virtual functions, and how to write multi-inheritance alternatives, how to apply controls using inheritance relationships.
Terms 24: Why do you use multiple inherits? Difficulty: 6 languages, including SQL99 standards, is also a big injury to "whether you should support single inheritance or more inheritance". This Terms invite you to discuss this topic.
1. What is more inheritance (Mi, Multiple Inheritance)? What additional possibilities and complexity have been introduced in C ?
2. Is Mi necessary? If necessary, use it as much as possible to list its usage, and arguate why MI should join the language; if it is not necessary, please argue why the single inheritance (SI) (and, possibly combined with the Java style interface) can replace more Inherit, even better than it, and why do not add MI to the language.
answer
1. What is more inheritance (Mi, Multiple Inheritance)? What additional possibilities and complexity have been introduced in C ?
Very briefly replied: MI refers to the ability to inherit from multiple (more than one) direct base class (Direct Class).
E.g:
Class Derived: Public Base1, Private Base2 {// ...};
The possibility of introducing MI in C is that the same (Direct or indirect) base class (Direct or indirect) base class may appear as its basic class (ancestor). Here is a simple example that the classic diamond shape is shown, as shown in Figure 4.
Here, B is two indirect classes (Indirect Class), once passed C1 once, and the other is passed through C2.
In this case, it is necessary to introduce another characteristic of C : virtual inheritance. The problem now is: The programmer wants to have a child object with base class B or two? If the answer is one, B should be a virtual base class, and Figure 4 has become a terrible death diamond. If the answer is two, B should be an ordinary (non-virtual) base class.
Finally, the main complexity of the virtual base class is that they must be directly initialized through the most underlying derived class. For details on this, please refer to [Stroustrup00], or [Meyers97] provisions 43. B
Di
C1
C2
Figure 4: Terrible death diamond (if D is virtual inherited from B)
Design guidelines
Avoid inheriting from multiple "non-protocol classes". (Protocol class is an abstract base class (Abstract base class), or abbreviated ABC, which is completely composed of pure virtual functions, no data member.)
2. Is MI necessary?
A short answer is: As long as the program can be written in assembly language (or lower language), some feature is absolutely "necessary". However, as most people will not go with simple C to write their own virtual function mechanisms, under certain occasions, there is no MI will make you a lot of time. Because of this, we now have this magical feature called MI. But the problem is - or, should at least the previous question should be changed to - Mi is a good thing? In short, it is indeed that some people think that MI is a bad idea, so it should be avoided anyway. This is wrong. Yes, if you have a bad consideration when using MI, it will make unnecessary coupling and complexity. However, any inheritance that is misuse is this (see Exceptional C [Sutter] Terms 24), but I believe that everyone will not think that inheritance is not a good thing. Also, yes, if you don't use MI, any program can be written, but you have to know that any procedure can also be written at all without inheriting. In fact, any program can be written in assembly language. But this is not to use the assembly language to write a procedure, it must be a good idea. Instead, you are not willing to do that.
2. If necessary, listen to its use occasion as much as possible, and demonstrate why MI should join the language; if it is not necessary, please argue why single inheritance (Si) (and, possibly combined with the Java style interface) Replacing more inheritance, even better than it, and why do not add MI to the language.
So, when do you use MI? In short, such MI is appropriate when it is suitable for each inheritance. Exceptional C Terms 24 provides a fairly detailed list that explains when to use inheritance. In the real world, MI's application can't escape the following three categories. 1. Combine the usage program module or library. The reason why I first put forward this, I will explain it later. Many classes are designed as base classes - that is, you have inherited from it. This naturally brings a problem: if you want to write a class, it uses two libraries, but each library requires you to inherit from it, what should you do at this time? _________________ 1. In order to some extent, the subject of this Terms inspires events that occur from the SQL standard meeting in June 1998. In that meeting, multi-inheritance was removed from the ANSI SQL99 standard. (If someone is interested in the database, you will know that MI in SQL4 is re-recovered in the revised form.) At the time, it was mainly because the proposed multi-inheritance specification existed Technical difficulties and is to think with Java these don't really support multi-inheritance language. In addition, just sitting there to listen to people in such a relatively late time to argue more inheritance, this itself makes people feel interesting. In the C world, we have made this kind of matter since this language; this makes me recall a few years ago (or more than this more near time) the intense debate, I will not endure Live some title, such as: "Mi is evil !!!" In the face of this situation, you generally cannot avoid a certain inheritance by modifying the library code. Because it may be a library purchased from a third party supplier, or may be a module developed by another project group in your company. No matter which situation, you can not only modify the code, you may even have no code! If so, MI is necessary; there is no other (natural) method to help you do what you have to do; at this time, MI is fully reasonable. In practice I found that I know how to use MI to combine the library provided by the supplier, this is the quality of each C programmer must have. Whether you use it frequently, you should definitely know it and understand it.
2. Protocol class (Interface class). In C , MI is the most appropriate, the safest application is to define the Protocol class - that is, the class consisting entirely of the pure virtual function. Because this base class has no data member, MI is unfairly complexity is completely avoided.
Interestingly, some language (or model) supports this MI through a non-inheritance mechanism. Java and COM are two examples. Strictly speaking, Java has multiple inherits, but it will implement the inheritance of the implementation is limited to single service. A Java class can implement multiple "interfaces", which is very similar to the pure abstract base class without data members in C . The COM itself does not inherit the concept (although when writing COM objects with C , this is a common implementation technology), but it also has the idea of "Composition of Oners", COM interface Similar to Java interface and C The combination of templates.
3. Easy (polymorphic) use. With inheritance, in any code accepted by the base class, we can use the derived object, which is a powerful function. In some occasions, if the same derived object can be used instead of several base classes, it will be useful, which is where MI shows the place. About this point has a good example, please refer to [Stroustrup00] 14.2.2, which demonstrates a MI-based design to construct an exception class; in that design, the bottom derived exception class may be Multiple direct base classes have a polymorphic IS-A relationship. Note that the 3rd point is largely overlap with the first, 2 points. At the other two points, at the same time, it is often useful to apply 3 points for the same reason.
Also think about another, don't forget: Sometimes, inheritance from two different base classes is not necessary. On the contrary, we must make every inheritance of different reasons. "Polymorphic LSP IS-A Public Inheritance" is not the only story (translation: see Terms 23); there are many other possible reasons for use inheritance. For example, a class may need to be inherited from a base class A to obtain access to the protection member of class A, at the same time, it also inherits from another base class B, with a polymorcite to realize a certain class B Musical function.