Effective C + + 35,36,37

Source: Internet
Author: User

35. The meaning of "being one" is embodied in the public succession.

The co-ownership of inheritance means "is one". such as Class B:public A. Each object that describes type B is an object of type A, and a has a broader concept than B. and b represents a more specific concept.

In C + + no matter what a function of the base class can actually take a derived class object, only the common ownership inheritance will be so. For co-ownership inheritance, such as AB. If there are two functions a function is void fun1 (a &a), and one function is void fun2 (b& B), then two objects a for AB. and B. are correct for FUN1 (a) and fun2 (b and fun1 (b)). Fun2 (a) is wrong. Note that this feature is only possible with co-ownership inheritance, which is different for private inheritance. And this is to say that the object of B is "a" object, but the array of B is not an array of a.

Common problems with public inheritance are the rules that apply to base classes and do not apply to derived classes. But public inheritance also requires that whatever is applicable to the base class object applies to the derived class object, and using public inheritance results in some wrong design.

For penguins and birds, a bird is a base class, with its mouth, wings and other data members. Another fly member function virtual void fly (); At the beginning you think birds have some attributes. And birds can fly, and then you have the feeling that the penguin public inheritance in birds, that is, penguins are a kind of bird, but the problem arises, penguins can not fly.

Let the penguin directly public inherit from the birds. This is a wrong design. So you want to improve it, while still using the premise of public inheritance.

1. There are very many birds in the world can not fly, so you divide the birds into two, flyingbird and Noflyingbird, divided into flying and will not fly two species of birds, both of which are publicly inherited from birds, and the Penguin public inheritance in Noflyingbird.

2. The penguin still has the fly () function, but once again it defines the fly function. Make it an execution error, so that penguins are birds, penguins can fly, but let penguins fly this operation is wrong.

This is an implementation of the ability to detect errors.

When you use some knowledge and common sense to design classes and use public inheritance, public inheritance is less effective, because the most critical problem is that the rules in the base class apply to the derived class object in the same way, and the objects that we want to implement with inheritance have different rules. In this case, the general use of "have a" and "use."

。 To implement the two relationships.


36. Differentiate between interface inheritance and implementation inheritance.

First, the interface is placed in public for external invocation. and implementation is the internal logic hidden in private. For the inheritance of classes, sometimes you want derived classes to inherit only the interfaces of member functions. Sometimes derived classes inherit the interface and implementation of a function at the same time. And agree that the derived class overrides the implementation, and sometimes the derived class inherits the interface and implementation of the class at the same time. But do not agree to change whatever thing.

Pure virtual functions must be declared again in the detail implementation class, which are often undefined in abstract classes. The purpose of defining pure virtual functions is to enable derived classes to inherit only the interface of the function. In the first case, such a situation is very easy to understand.

But the pure virtual function is actually able to provide a definition.

For the other and the third case, the interface and implementation of the inherited function are generally implemented using virtual functions.

And what needs to be improved is. For a virtual function in a base class, it has a certain implementation. Derived classes can inherit this interface and implementation, both directly inheriting the interface in the base class, and can override the implementation of this interface.

This is very scientific, but there is another problem when a new derived class inherits the base class. Because a virtual function is used in this class to interface, the new program ape forgets to declare the virtual function again and give the new implementation logic to err on the wrong use of the default logic in the virtual function. To provide a more secure base class, use pure virtual functions as interfaces, so that pure virtual functions have their own default implementations, when derived classes inherit. Direct invocation of the base class pure virtual function implementation:

Class a{public:virtual void fun () const = 0;}; void A::fun () const{cout<< "Class A" <<ENDL;} Class b:public a{public:virtual void Fun () const;}; void B::fun () Const{a::fun ();}
As you can see above, use a pure virtual function. However, with the default implementation, the derived class must declare this pure virtual function once again, and for the default implementation of the base class, in addition to calling the pure virtual function of the base class directly above, it is also possible to set a default implementation function in protected in the base class, such as void Defaultfun () Const. The derived class inherits this default implementation and then calls the default implementation function in another defined virtual function of the derived class.

This is actually a different situation, the interface and implementation of the inherited function, and can be changed to implement. Virtual functions are generally used. However, it is more secure to use pure virtual functions with default actions. Security is a very important issue, assuming that security is not considered, a lot of the issues discussed in the effective C + + book are meaningless, given the assumption that you have defined the previous program settings. Know what to do, what not to do, and not make mistakes, but for a program development. Not one of them is finished. When you understand your own set-up, others do not know that the person who maintains your code does whatever security they feel they should be able to do, but is extremely insecure because you considered it too carefully. So consider the security issue carefully. Write the code as perfectly safe as possible.

For the third case, declare the non-virtual function. The purpose is to make the derived class inherit the interface and mandatory implementation of the function, and because the non-virtual function of the base class should not be declared and defined again in the derived class, the implementation of the non-virtual function is not altered.

Therefore, to understand pure virtual functions, simple virtual functions and non-virtual function declarations and functional differences. Do not worry about the efficiency of virtual functions, because this is really a small problem, all the base class should be virtual function.

Some functions should not be defined once again in a derived class to define them as non-virtual functions.


37. Never define the inherited non-virtual function again.

First, for another non-virtual function that defines inheritance, it is called hiding the function. This is an infrequently used thing, and it is precisely because of this setting that you never define the inherited non-virtual function again.

The reason for this is also very easy to understand, but also a multi-state advantage:

Class A{public:void Fun () const{cout<< "Class A" <<endl;}}; Class B:public A{public:void Fun () const{cout<< "Class B" <<endl;}}; int main () {b* b = new B (); * a = B;b->fun (); A->fun ();
For the code above, for the same object, the object that B points to, when it is converted to a base-class pointer, because it is statically bound, it points to a different function, obtaining different results. While polymorphism is dynamically bound, the point function points to the same address through a virtual pointer.
The conclusion is that for the object of Class B, once again the function fun () is defined. Its behavior is indeterminate, and the determinant is not related to the object itself, but depends on the type of declaration that points to it, and the reference and the pointer exhibit this unusual behavior, which is unreasonable.

and theoretically. For public inheritance It means "is a", and for B once again the implementation in a is defined, B is not "a".



Effective C + + 35,36,37

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.