Destructor
If a class is to be inherited by others, it is usually declared as a virtual function. Otherwise, the following code will be undefined. Base * P = new derived (); Delete P; conversely, if you do not want others to derive your class, do not declare the Destructor as a virtual function, if the other party is a cainiao, you cannot. In extreme cases, as long as the user ensures that there is no multi-state structure (as shown in the preceding example), it can also be integrated.
Inheritance and Access PermissionsThe private member of the base class can only be accessed by the friends of the base class or the base class, that is, it cannot be accessed by the callers (customers) outside the class or by the quilt class. It may be a relatively loose choice. The protected member allows access from the derived class, but rejects access from external callers. <C ++ primer> A detailed difference is provided. A derived class cannot use a base class object. this method uses the protected member variable, but you can use the derived class object. this method is used to protect member variables. Of course, it is feasible to directly use the inherited protected member variable, because it is equivalent to this-> protecting member variables. In fact, subclass can only access the public and protected members of the base class. If it is a public inheritance, the public and protected members of the base class are still public and protected in the subclass; if it is a protected inheritance, it becomes a protected member; if it is a private inheritance, all are changed to private members.
Public inheritanceIn most cases, public inheritance should meet the following two conditions: 1) derived class IS-A base class (IS-A Principles) 2) derived class WORKS-LIKE-A base class (WORKS-LIKE-A Principles) a compliance with the first principle, but the example does not conform to the second principle-the base class rectangle and the public derived class square. Rectangle provides the virtual function setwidth to allow the user to set the width. However, the derived class will reload this method and ensure that the width is modified while the height has been modified. The behavior of the square class is no longer the same as its parent class, so public inheritance cannot be used to express the relationship between them, although a square is a rectangle in mathematics, but this is C ++, not mathematics. :) These two principles reflect one of the five object-oriented principles: LSP (liskov substitution principle ). in such an extreme situation, if the designer can ensure that users do not have the opportunity to use subclasses in a multi-state manner, it is also possible to use public inheritance for convenience purposes. For example, <exceptional C ++> about ci_char_traits public inheritance char_traits <char> class, and rewrite several static member functions. This is because STL does not use this class in the form of polymorphism. Here we use the new replacement principle: glsp, G stands for generic. Any Type passed as template parameters must comply with the requirements of this parameter and provide some member functions.
Protection inheritanceProtection inheritance is usually used for re-inheritance. If the class I designed needs to inherit the public and protected members of a class, and I also want these Members to be accessed by the derived classes of the class I designed, in this case, I can use protection inheritance. Of course, public inheritance can achieve this purpose, but public inheritance must follow two principles. In addition, we need to protect inheritance. Protection inheritance only inherits the existing implementation of a class and does not need to comply with the two principles of public inheritance, or derived class is not a base class, and will not work like a base class.
Private inheritanceThe purpose of private inheritance is similar to that of protection inheritance, but all the base class members are converted into private members, so they cannot be inherited. Both private Inheritance and Protection inheritance express the same meaning. I use the implementation of an existing class to implement my class, but for code reuse, there is no other purpose. (Is-implemented-in-terms-of depends on something ).
Inheritance and CouplingRegardless of how the inheritance always associates the derived class with the parent class in a strong way, So <predictional C ++> always recommends that you prioritize the use of the HAS-A as much as possible. This encoding may be large, but it brings more flexibility. For example, you can include multiple instances to hide data members behind the compiler firewall (using pimp technology ).
Multi-InheritanceIf multiple parent classes have members of the same name, the compiler reports ambiguous errors when the subclass is called. It shows that it is a solution to indicate which parent class you intend to use. If your two parent classes inherit from the same grandfather class, this is Diamond inheritance. All members of the grandparent class will be inherited twice by your two parent classes. The result is: 1) the member variables of the grandparent class will have a copy in each of the two child classes, the result is that your class has two copies at the end; 2) using inherited grandfather class members will lead to ambiguity in the compiler because there are two paths. The adapter mode can be implemented by using multiple inheritance methods. The adapter public inherits from the target and the private inherits from the adaptee. However, according to the <exceptional C ++> principle, try to use the has-a method instead of private inheritance unless you want to access the protected member of adaptee.
Virtual inheritanceVirtual inheritance can solve the problem of multiple copies of grandfather-class member variables caused by multiple diamond inheritance. <Strong tive C ++> note that virtual inheritance brings additional space and time overhead. Therefore, it is better not to use virtual inheritance. It is best not to put member variables in the virtual base class, because the underlying derived class is always responsible for initializing the virtual base class. This <strong tive C ++> is not clear, and I do not know what the initialization details are?
Overload FunctionsIf it is not a virtual function, do not reload it. There are two reasons: 1) because it does not have the dynamic binding feature of virtual functions, when you use a pointer to the base class to call a function, this function has been reloaded by you, in addition, the pointer actually points to your subclass, but the compiler will never call the subclass version, because the static type of the pointer has the final say, and the base class version is called. 2) Non-virtual functions mean that the derived classes must inherit interfaces and implementations and should not be modified, because they represent immutability over specicity. Reference: <C ++ primer> 4th edition <strong tive C ++> 3th edition <Design Patterns> <strong tional C ++> Chen Yu