Basic memo: Implementation of polymorphism (heavy load, virtual function, abstract class)

Source: Internet
Author: User

1. Function Overloading

The polymorphism supported by static Association is known as the Polymorphism or static polymorphism during compilation. That is to say, the process of determining the specific operation object of the same name operation is completed during compilation. In C ++, function overloading and operator overloading can be used to achieve polymorphism during compilation.

2. Virtual Functions

The polymorphism supported by dynamic Association editing is called the "too many" or "dynamic polymorphism" during running. That is to say, the process of determining the specific operation object for an operation with the same name is completed during running. In C ++, virtual functions can be used to implement Runtime polymorphism.

2. 1. Virtual Function Definition

Virtual functions are defined in the base class, that is, the member functions that need to be defined as virtual functions in the base class are declared as virtual. When a member function in the base class is declared as a virtual function, it can be redefined in the derived class. When being redefined in a derived class, its function prototype, including the return type, function name, number and type of parameters, and the order of parameters must be exactly the same as that in the base class.

The format is as follows:

Virtual <function type> <Function Name> (parameter table) {function body}

For example, the Code for solving the problem of blog polymorphism is as follows:

# Include <iostream> using namespace STD; class animal {public: void sleep () {cout <"Animal sleep" <Endl;} virtual void breathe () // Add virtual {cout <"Animal breathe" <Endl ;}}; class fish: Public animal {public: void breathe () {cout <"Fish bubble" <Endl ;}; int main () {fish FS; animal * an = & FS; An-> breathe (); system ("pause ");}

It is solved by adding a virtual problem. Output result:

In fact, when the member function breathe () in the base class is declared as a virtual function, the compiler finds that there are virtual functions in the animal class during compilation, in this case, the compiler creates a virtual table for each class containing virtual functions. The table is a one-dimensional array that stores the addresses of each virtual function. In the above Code, both the animal class and the fish class contain a virtual function breathe (). Therefore, the compiler creates a virtual table for the two classes, as shown in.

Virtual tables like animal and fish

In the above Code, after the FS object of the fish class is constructed, its internal virtual table pointer is initialized to the virtual table of the fish class. After the conversion, call an-> breathe (). Because an actually points to a fish object, the virtual table pointer inside the object points to a virtual table of the fish class, therefore, the breathe () function of the fish class is called.

Notes when using derived object pointers:

1. The Declaration indicates that the pointer to the base class object can point to the object of its public derived class, but cannot point to the object of its private derived class.

2. It can be declared as a pointer to a base class object pointing to its public derived class object, but cannot be declared as a pointer to a derived class object pointing to the base class object.

3. the Declaration refers to a pointer to a base class object. When it points to an object of its public derived class (which contains 1st items), it can only directly access the members inherited from the base class in the derived class, you cannot directly access the Members defined in the public derived class. To access a member of its public derived class, you can convert the base class pointer to a derived class pointer by explicit type conversion. For example:

# Include <iostream> using namespace STD; Class B {public: void VF () {cout <"this is Class B" <Endl ;}}; Class D: public B {public: void VF () {cout <"this is Class D" <Endl ;}; int main () {B, * pb; d, * PD; Pb = & B; Pb-> VF (); Pb = & D; // 1st million records. Pb-> VF (); // Pd = & B; // The number of records violates 2nd. Invalid conversion from 'B *' to 'd * '// Pd-> VF (); Pd = (D *) & B; // meet 3rd conditions. Pd-> VF (); Pd = & D; Pd-> VF (); System ("pause ");}

If you change VF to the virtual type, there are:

# Include <iostream> using namespace STD; Class B {public: Virtual void VF () {cout <"this is Class B" <Endl ;}; Class D: public B {public: void VF () {cout <"this is Class D" <Endl ;}; int main () {B, * pb; d, * PD; Pb = & B; Pb-> VF (); Pb = & D; // 1st million records. Pb-> VF (); // Pd = & B; // The number of records violates 2nd. Invalid conversion from 'B *' to 'd * '// Pd-> VF (); Pd = (D *) & B; // meet 3rd conditions. Here is polymorphism. Pd-> VF (); Pd = & D; Pd-> VF (); System ("pause ");}

The virtual function can realize polymorphism well.Note the following when using virtual functions::

1. The declaration of virtual functions can only appear in the class function prototype.StatementIs not included in the function bodyImplementationIn addition, only the protected or public members in the base class can be declared as virtual functions.

2. When a new virtual function is redefined in a derived class, the keyword virtual can be written or not written, but this keyword should be written in case of confusion.

3. Dynamic Association editing can only passMember FunctionsTo call or passPointer and referenceTo access virtual functions. If you access virtual functions in the form of object names, static concatenation is used.

InIn the derived classRedefinesVirtual FunctionsIs another form of function overload, But itThere are also the following differences with function overloading:

1. For general function overloading, the parameter or parameter type of the function must be different, and the return type of the function can be different.

2. When you reload a virtual function, the function name, return type, number of parameters, parameter type, and Parameter order must be exactly the same as the virtual function in the base class.

3. If only the return type is different and the rest are the same, the system will give an error message.

4. If the function name is the same, and the number of parameters, the type of parameters, or the order of parameters are different, the system considers the function as a normal function overload, and the features of the virtual function will be lost.

2.2 multi-level inheritance and virtual functions

Examples of original ecological multi-level inheritance:

#include<iostream>using namespace std;class B{      public:             int ms;      public:            void set()             {                  cout<<"Base set"<<endl;                  }      };class D:public B{      public:             void set()             {                  cout<<"D set"<<endl;                  }      };class DD:public D{      };class DDD:public DD{      public:             void set()             {                  cout<<"DDD set"<<endl;                  }      };class DDDD:public DDD{            };class DDDDD:public DDDD{      };int main(){    DD d;    d.set();    DDDD dddd;    dddd.set();    DDDDD ddddd;    ddddd.set();    system("pause");    }

The above Code results show that if the class does not have a corresponding member function, it will be searched for at the upper level until the required member function appears. Set above. D. If the set class does not exist in the DD class, search for it and find the member function of the parent class closest to it.

Multi-level inheritance can be seen as a combination of multiple single inheritance. The multi-level inherited virtual functions call the same as the single-inherited virtual functions. A single virtual function is inherited no matter how many times, the features of its virtual functions remain independent of the number of inherited functions. For example:

# Include <iostream> using namespace STD; class base {public: Virtual ~ Base () {} virtual void func () {cout <"base func" <Endl ;}; class derived1: public base {void func () {cout <"derived1 func" <Endl ;}; class derived2: Public derived1 {void func () {cout <"derived2 func" <Endl ;}}; void test (base & B) // reference mode {B. func () ;}int main () {Base B; derived1 D1; derived2 D2; test (B); test (D1); test (D2 ); system ("pause ");}

In the above Code, the keyword virtual is added before the destructor, And the Destructor is called a virtual destructor.

Example of code extension:

# Include <iostream> using namespace STD; class base {public: Virtual ~ Base () {} virtual void func () {cout <"base func" <Endl ;}; class derived1: public base {void func () {cout <"derived1 func" <Endl ;}; class derived2: Public derived1 {/* void func () {cout <"derived2 func" <Endl ;} */}; Class derived3: Public derived2 {void func () {cout <"derived3 func" <Endl ;}}; class derived4: Public derived3 {void func () {cout <"derived4 func" <Endl ;}}; void test (base & B) // reference mode {B. func () ;}int main () {Base B; derived1 D1; derived2 D2; derived3 D3; derived4 D4; test (B); test (D1); test (D2 ); test (D3); test (D4); System ("pause ");}


Note that D2 uses a member function of its parent class.

When using virtual destructor, pay attention to the following two points:

1. As long as the destructor of the base class is declared as a virtual function, the destructor of the derived class automatically become a virtual function regardless of whether the virtual keyword is used for declaration.

2. If the destructor of the base class is a virtual function, when the derived class does not define the destructor, The Destructor generated by the compiler is also a virtual function.

In general, it is best to declare the destructor of the base class as a virtual function in the program.This will make the destructor of all derived classes automatically become virtual functions. In this way, if the delete operator is used in the program to delete an object, and the delete operator operates on the object pointing to the base class pointer of the derived class, the system will call the corresponding destructor; otherwise, the system only executes the destructor of the fern, instead of the destructor of the derived class, which may cause exceptions.

Constructors cannot be declared as virtual functions.This is because the creation process of class objects is not completed when the constructor is executed. Of course, the association between functions and class objects cannot be discussed.

Supplementary example:

#include <iostream> using namespace std; class A { protected:            int m_data; public:         A(int data = 0):m_data(data) { }         int GetData() { return doGetData(); }         virtual int doGetData() { return m_data; } }; class B:public A {       protected:                  int m_data;       public:               B(int data = 1): m_data(data) { }               int doGetData() { return m_data; } }; class C:public B {       protected: int m_data;       public:               C(int data = 2):m_data(data) { } }; int main() {     C c(10);     cout << c.GetData() << endl;     cout << c.A::GetData() << endl;     cout << c.B::GetData() << endl;     cout << c.C::GetData() << endl;     cout << c.doGetData() << endl;     cout << c.A::doGetData() << endl;     cout << c.B::doGetData() << endl;     cout << c.C::doGetData() << endl;     system("pause");    return 0;     } 

1 // getdata in C is not defined, and so is B. Therefore, a is called. Dogetdata of A is a virtual function. Therefore, if B is called, dogetdata of B is returned: m_data1 // same as 1 // same as 1 // same as 1 // same as 1 // dogetdata in C is not defined. B is called, return B: m_data0 // directly call dogetdata in a, return a: m_data1 // call doggetdata in B, return B: m_data1 // same as C. dogetdata () press any key to continue...

3. Pure virtual functions and abstract classes

An abstract class is a special class that provides a unified operation interface. Abstract classes are created to use abstract class member functions in a multi-state manner. Abstract classes are classes that contain pure virtual functions.

3.1 pure virtual functions

Definition form:

Virtual <function type> <Function Name> (parameter table) = 0;

Pure virtual functions provide a unified interface for the derived classes. The implementation of pure virtual functions can be left to the derived classes. Generally, an abstract class contains at least one pure virtual function.

Example:

#include<iostream>using namespace std;class Point{      protected:                int x0,y0;      public:             Point(int i,int j)             {                       x0=i;                       y0=j;                       }      virtual void set()=0;      virtual void draw()=0;      };class Line:public Point{      protected:                int x1,y1;      public:             Line(int i=0,int j=0,int m=0,int n=0):Point(i,j)             {                      x1=m;                      y1=n;                      }             void set(){cout<<"Line_set()"<<endl;}             void draw(){cout<<"Line_draw()"<<endl;}      };class Ellipse:public Point{      protected:                int x2,y2;      public:             Ellipse(int i=0,int j=0,int p=0,int q=0):Point(i,j)             {                         x2=p;                         y2=q;                      }             void set(){cout<<"Ellipse_set()"<<endl;}             void draw(){cout<<"Ellipse_draw()"<<endl;}      };void drawobj(Point *p){     p->draw();     }void setobj(Point *p){     p->set();     }int main(){  Line *li=new Line();//new Line;  drawobj(li);  setobj(li);  cout<<endl;     Ellipse *el=new Ellipse();//new Ellipse;   drawobj(el);   setobj(el);   cout<<endl;       Line *li2=new Line;   drawobj(li2);   setobj(li2);   cout<<endl;      Ellipse elp;   drawobj(&elp);   setobj(&elp);   cout<<endl;           system("pause");    } 

In the above Code, the line and ellipse classes all inherit from the Point class. To realize polymorphism in this program, you must define the Set () function and draw () function () the function is a virtual function. At the same time, because the points do not need to be drawn in the application, the Set () and draw () Functions of the point are defined as virtual functions. In the main function main (), after creating the line Object and ellipse object, you can call these two functions with the same name. This is the role of a virtual function. It is generally used when the base-class function has no specific operation, and this function may be required in a derived class.

3.2 abstract class

Classes that contain virtual functions are called abstract classes. Abstract classes are special classes that are created for the purpose of abstraction and design and are at the upper layer of the hierarchy of inheritance.Abstract classes cannot create objects. To emphasize that a class is an abstract class, you can declare the constructor of this class as a protected access control permission.

The main function of an abstract class is to organize the relevant classes in an inheritance layer. abstract classes provide them with a public root. The related subclass is derived from this root. Abstract classes depict the General Semantics of the Operation interfaces of a group of child classes. These semantics are also passed to child classes. In general, an abstract class only describes the operation interfaces of this group of sub-classes, and the complete implementation is left to the sub-classes. When using abstract classes, pay attention to the following issues:

1. An abstract class can only be used as a base class of other classes. It cannot be used to create an abstract class object. Because its pure virtual function does not have a defined function, its pure virtual function implementation is provided by the derived class.

2. abstract classes cannot be used as parameter types, function return types, or explicitly converted types.

3. You can declare the object pointer or object reference of an abstract class to access the object Member of the derived class and implement dynamic Association.

4. If no abstract classFunction bodies of all pure virtual functions, The derived class is still an abstract class. If the derived class of the abstract class provides the function bodies of all pure virtual functions, this derived class is no longer an abstract class and can create its own objects. Example:

# Include <iostream> using namespace STD; Class vehicle {protected: Float speed; int total; public: Vehicle (float speed, int total) {vehicle: speed = speed; // duplicate member variables and function parameters. Note: To distinguish between member variables and function parameters, otherwise, the initialization may have problems with vehicle: Total = total; // or this-> total = total;} virtual void showmember () = 0 ;}; class car: public vehicle {protected: int AIRD; public: Car (int aird, float speed, int total): Vehicle (speed, total) {CAR: AIRD = AIRD;} void showmember () {cout <"speed is: "<speed <Endl; cout <" toatal is: "<total <Endl; cout <" AIRD is: "<AIRD <Endl ;}; int main () {car C (250,150, 4); C. showmember (); System ("pause ");}

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.