(a)
Class Shape {public: virtual void draw () const = 0; virtual void error (const string& msg); int ObjectID () const; }; Class Rectangle:public Shape {...}; Class Ellipse:public Shape {...};
The concept of public inheritance seems simple. It seems very easy to surface. However, after careful examine, we will find that the concept of public inheritance actually consists of two interdependent parts: the inheritance of function interfaces and the inheritance of function implementations. The difference between the two is exactly the same as the differences between the function declaration and the function implementation. The interface of the member function is always inherited, because public inheritance means is-a.
Pure Virtualfunction Two salient features: (1) must be "inherited" by whateverclassanother statement. (2) They are in the abstractclassis not normally defined in the.
Two
declaring a is to let
sharp* PS1 = new Rectangle;ps1->draw (); sharp* PS2 = new Rectangle;ps2->draw ();p s1->shape::d Raw ();//Call Shape Drawps2->shape::d Raw ();
Three
declaration . is to let the inherits the interface and default implementation of this function.
Agree impure Virtual the function at the same time specifies the function declaration and function default behavior, but it is possible to cause a crisis.
Class Airport {...}; Class Airplane {public: virtual void Fly (const airport& destination);}; void Airplane::fly (const airport& destination) { //default code, fly airplane to specified destination} class Modela:public airplane {...}; Class Modelb:public airplane {...}; Class Modelc:public Airplane {...//the Fly function is not declared, but it does not want the default flight}; Airport PDX (...); airplane* pa = new Modelc; ... pa->fly (PDX); Did not say "I want to inherit the default behavior, a catastrophe"
This program tries to fly MODELC with Modela and MODELB flight modes.
The problem is not that airplane::fly () has a default behavior, but that MODELC inherits the default behavior when it does not understand "I want". We can do "provide default implementations to derived classes. But unless they understand the requirement, it is not to be discussed.
Workaround (1): The trick here is to cut the connection between the "virtual function interface" and its "default implementation." Here's a procedure:
Class Airplane {public: virtual void Fly (const airport& destination) = 0; Protected: void Defaultfly (const airport& destination); void Airplane::d efaultfly (const airport& destination) { //default behavior, fly aircraft to destination}
Fly has been transformed into a pure virtual function that simply provides a flight interface. The default behavior is defaultfly out of today's airplane class.
If you want to use the default implementations (such as Modela and Modelb). Ability to make an inline call to Defaultfly in fly:
Class Modela:public Airplane {public: virtual void Fly (const airport& destination) { defaultfly ( destination); } ... }; Class Modelb:public Airplane {public: virtual void Fly (const airport& destination) { defaultfly ( destination); } ... };
now MODELC cannot accidentally inherit the wrong fly implementation code. Because the pure virtual function in Airplane forces MODELC to provide its own fly version number:
Class Modelc:public Airplane {public: virtual void Fly (const airport& destination); ... }; void Modelc::fly (const airport& destination) { //To fly a C-plane to a specified destination}
Like these words,This method is not safe. The program ape is still likely to be troublesome due to clipping (copy-and-paste) code, but it is more than the original design worth relying on.
Some people object to providing interfaces and default implementations with different functions, as in the above fly and defaultfly.
So we came up with the following solution:
workaround (2):
We are able to use the pure virtual function to declare again in the derived class. But they can have their own realization "the fact.
Here's how the airplane inheritance system defines a pure virtual function:
Class Airplane {public: virtual void Fly (const airport& destination) = 0; ... }; void Airplane::fly (const airport& destination)//pure virtual function Implementation { //default behavior, fly airplane to specified destination} class Modela:public Air Plane {public: virtual void Fly (const airport& destination) { airplane::fly (destination); }}; class Modelb:public Airplane {public: virtual void Fly (const airport& destination) { airplane::fly (destination) ; } }; Class Modelc:public Airplane {public: virtual void Fly (const airport& destination) ... }; void Modelc::fly ( Const airport& Destination) { //Fly the C-plane to the specified destination}
Four
assuming that the member function is a non-virtual function, it means that it is not intended to behave differently in derived classes. The Non-virtual member function shows theinvariance overrides its specificity, no matter how special derived class becomes. Its behavior can not be changed.
The purpose of declaring the Non-virtual function is to make the interface of the derived class inheritance function and a mandatory implementation .
Class Shape {public: ...
To see Shape::objectid's statement: To be able to do is "every Shape object has a function to produce an object identifier: the identification code is always used in the same way, and the method is determined by the Shape::objectid definition, whatever derived Class should not attempt to change its behavior. "
Please remember:
1. interface inheritance and implementation inheritance are different. under public inheritance. derived classes always inherits the interface of base class.
2. the Pure virtual function specifies only the interface inheritance in detail.
3. The impure virtual function specifies interface inheritance and default implementation inheritance in detail.
4. The non-virtual function specifies the interface inheritance as well as the mandatory implementation inheritance.
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
Effective C + +: Provision 34: Differentiate between interface inheritance and implementation inheritance