Analysis on the polymorphism mechanism of c ++

Source: Internet
Author: User

I. Summary of polymorphism Mechanism

1. Review instances

Previously, when writing a C ++ program, we used to implement a function that calculates the absolute value of a number. At that time, we did a heavy load of three functions, int FABS (int x ), double FABS (Double X) and float FABS (floatx), the compiler can decide which function to call based on the type of the input parameter. In this way, can we understand that the same behavior has multiple forms of representation? Take Different Processing Methods Based on the object type, which is actually polymorphism.

2. The nature of Polymorphism

Send messages to objects that really need them through some form of generalized interfaces. So how can we determine the object to which the message is sent? Polymorphism can be divided into polymorphism during compilation and polymorphism during runtime. polymorphism during compilation means that the compiler knows which method or function to call, during running, the message sending is postponed until the program is running, and the object receiving the message is determined based on the reference or pointer.

2. polymorphism during compilation-static binding

1. Function Overloading

2. Macro Polymorphism

# Define add (A, B) (A) + (B)

Int A = 1, B = 2;

String S1 = "AA", S2 = "BB ";

Cout <add (A, B );

Cout <add (S1, S2 );

When the program is compiled, add (A, B) and add (S1, S2) are compiled into two integers and two string join expressions respectively.

Iii. Runtime polymorphism-dynamic binding

1. Public inheritance and virtual functions are the cornerstone of C ++ Runtime polymorphism

Code example:

 

# Include <iostream >#include <string> # include <cmath> using namespace STD; Class shape {public: Virtual double area () = 0 ;}; class point {PRIVATE: double X; Double Y; public: Point (double x = 0, Double Y = 0) {This-> X = x; this-> Y = y ;} point (const point & Other) {x = Other. x; y = Other. y;} Point & operator = (const point & Other) {This-> X = Other. x; this-> Y = Other. y; return * This;} void setx (Double X) {This-> X = x;} void sety (Double Y) {This-> Y = y ;} double getx () const {return X;} double Gety () const {return y ;}}; class rectangle: Public shape {private: Point left_up; // point right_bottom in the upper left corner; // point double width in the lower right corner; double height; void setwidth () {width = FABS (left_up.getx ()-right_bottom.getx ());} void setheight () {Height = FABS (left_up.gety ()-right_bottom.gety ();} public: rectangle (const point & left, const point & right) {left_up = left; right_bottom = right; setwidth (); setheight ();} rectangle (double left_x, double left_y, double right_x, double right_y) {left_up = point (left_x, left_y ); right_bottom = point (right_x, right_y); setwidth (); setheight ();} rectangle (const rectangle & Other) {left_up = Other. left_up; right_bottom = Other. right_bottom; setwidth (); setheight () ;}rectangle & operator = (const rectangle & Other) {left_up = Other. left_up; right_bottom = Other. right_bottom; setwidth (); setheight (); return * This;} double area () {return width * Height ;}}; const double Pi = 3.1415926; Class circle: public shape {PRIVATE: Point center; double radius; public: Circle (const point & C, double r) {center = C; radius = r ;} circle (double x = 0, double Y = 0, double r = 0) {center = point (x, y); radius = r;} circle (const circle & Other) {center = Other. center; radius = Other. radius;} circle & operator = (circle & Other) {center = Other. center; radius = Other. radius; return * This;} double area () {return POW (radius, 2) * PI ;}}; void getareasize (shape * SP) {cout <"area is: "<SP-> area () <Endl;} void main () {rectangle R (1.12, 2.22,); Circle C (, 2 ); getareasize (& R); getareasize (& C );}

 

In the above example, we use public inheritance, pure virtual functions, and pointer to the base class to realize the polymorphism during runtime.

 

Iii. Pure virtual functions and virtual functions

1. Comparison of Basic Forms

Virtual return type fun (parameter table)= 0; // Pure virtual function

Virtual return type fun (parameter table) // virtual function

{

// To do something

}

2. Pure virtual functions

(1) pure virtual functions are equivalent to interfaces without implementation.

(2) classes that contain pure virtual functions are called abstract classes. abstract classes cannot be instantiated. to instantiate a derived class of an abstract class, you must implement pure virtual functions of the base class, that is, redefine the function.

3. Virtual Functions

(1) virtual functions are non-static and non-inline functions.

(2) A derived class can override (override) the virtual function of the base class.

(3) virtual functions and public inheritance can realize polymorphism at runtime.

(4) When you use a base class pointer or reference a public derived class pointing to this base class, the virtual function of the base class you call through a pointer or reference is actually the version of the override of its derived class.

Iv. Virtual table

1. Definition

The virtual function table is used to store the virtual function address of a class, as shown in:

 

2. Role

This table is like a map to solve the problem of which function is actually called by polymorphism during running.

3. storage location

The C ++ compiler ensures that the VT address is stored at the frontend of all class elements in the object instance.

4. Instance

# Include <iostream> using namespace STD; class base {public: Virtual void F () {cout <"base: F ()" <Endl ;} virtual void g () {cout <"base: G ()" <Endl;} virtual void H () {cout <"base: H () "<Endl ;}}; class derive: public base {public: Virtual void F1 () {cout <" derive: F1 () "<Endl ;} virtual void G1 () {cout <"derive: G1 ()" <Endl;} virtual void H1 () {cout <"derive: H1 () "<Endl ;}}; void main () {typedef void (* Fun) (void); // fun indicates pointing to void F (void) function pointer type fun pfun = 0; // derive D; Base B; int I; int vt_addr = * (reinterpret_cast <int *> (& B )); // address of the virtual table for (I = 0; I <3; I ++) // call the three virtual functions {int fun_addr = * (reinterpret_cast <int *> (vt_addr) + I); pfun = reinterpret_cast <fun> (fun_addr ); pfun ();}}

Output:

V. vt mechanism-General inheritance without virtual function coverage

1. Instance

# Include <iostream> using namespace STD; class base {public: Virtual void F () {cout <"base: F ()" <Endl ;} virtual void g () {cout <"base: G ()" <Endl;} virtual void H () {cout <"base: H () "<Endl ;}}; class derive: public base {public: Virtual void F1 () {cout <" derive: F1 () "<Endl ;} virtual void G1 () {cout <"derive: G1 ()" <Endl;} virtual void H1 () {cout <"derive: H1 () "<Endl ;}}; void main () {typedef void (* Fun) (void); // fun indicates pointing to void F (void) function pointer type fun pfun = 0; derive D; int I; int vt_addr = * (reinterpret_cast <int *> (& D )); // address of the virtual table for (I = 0; I <6; I ++) // call six virtual functions {int fun_addr = * (reinterpret_cast <int *> (vt_addr) + I); pfun = reinterpret_cast <fun> (fun_addr ); pfun ();}}

 

2. Output:

 

3. Memory organization form

 

 

 

Vi. vt mechanism-General inheritance with virtual function coverage

1. Instance

# Include <iostream> using namespace STD; class base {public: Virtual void F () {cout <"base: F ()" <Endl ;} virtual void g () {cout <"base: G ()" <Endl;} virtual void H () {cout <"base: H () "<Endl ;}}; class derive: public base {public: void F () // at this time, F () is still a virtual function {cout <" derive: F () "<Endl;} virtual void G1 () {cout <" derive: G1 () "<Endl;} virtual void H1 () {cout <" derive:: H1 () "<Endl ;}; void main () {typedef void (* Fun) (void); // fun indicates pointing to void F (void) function pointer type fun pfun = 0; derive D; int I; int vt_addr = * (reinterpret_cast <int *> (& D )); // address of the virtual table for (I = 0; I <5; I ++) // call the three virtual functions {int fun_addr = * (reinterpret_cast <int *> (vt_addr) + I); pfun = reinterpret_cast <fun> (fun_addr ); pfun ();}}

 

2. Output

 

3. Memory organization form

 

 

 

4. Runtime polymorphism

Base * B = newderive (); // B is a pointer to a derived class

B-> F (); // the function of the derived class is called at this time.

When the pointer B is used to find F () in the virtual function table, the derived class F () is found, so the running polymorphism occurs.

 

VII. vt mechanism-Multi inheritance without virtual function coverage

1. Instance

#include <iostream>using namespace std;class Base1{public:virtual void f(){cout<<"Base1::f()"<<endl;}virtual void g(){cout<<"Base1::g()"<<endl;}virtual void h(){cout<<"Base1::h()"<<endl;}};class Base2{public:virtual void f(){cout<<"Base2::f()"<<endl;}virtual void g(){cout<<"Base2::g()"<<endl;}virtual void h(){cout<<"Base2::h()"<<endl;}};class Base3{public:virtual void f(){cout<<"Base3::f()"<<endl;}virtual void g(){cout<<"Base3::g()"<<endl;}virtual void h(){cout<<"Base3::h()"<<endl;}};class Derive:public Base1,public Base2,public Base3{public:virtual void f1(){cout<<"Derive::f1()"<<endl;}virtual void g1(){cout<<"Derive::g1()"<<endl;}};void main(){typedef void (*Fun)(void);Fun pfun;Derive d;int VT_addrofBase1=*(reinterpret_cast<int*>(&d));int VT_addrofBase2=*(reinterpret_cast<int*>(&d)+1);int VT_addrofBase3=*(reinterpret_cast<int*>(&d)+2);int i;for(i=0;i<5;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase1))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}for(i=0;i<3;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase2))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}for(i=0;i<3;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase3))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}}

 

2. Output

 

3. Memory organization form

 

VIII. vt mechanism-multiple inheritance with virtual function coverage

1. Instance

#include <iostream>using namespace std;class Base1{public:virtual void f(){cout<<"Base1::f()"<<endl;}virtual void g(){cout<<"Base1::g()"<<endl;}virtual void h(){cout<<"Base1::h()"<<endl;}};class Base2{public:virtual void f(){cout<<"Base2::f()"<<endl;}virtual void g(){cout<<"Base2::g()"<<endl;}virtual void h(){cout<<"Base2::h()"<<endl;}};class Base3{public:virtual void f(){cout<<"Base3::f()"<<endl;}virtual void g(){cout<<"Base3::g()"<<endl;}virtual void h(){cout<<"Base3::h()"<<endl;}};class Derive:public Base1,public Base2,public Base3{public:virtual void f(){cout<<"Derive::f()"<<endl;}virtual void g1(){cout<<"Derive::g1()"<<endl;}};void main(){typedef void (*Fun)(void);Fun pfun;Derive d;int VT_addrofBase1=*(reinterpret_cast<int*>(&d));int VT_addrofBase2=*(reinterpret_cast<int*>(&d)+1);int VT_addrofBase3=*(reinterpret_cast<int*>(&d)+2);int i;for(i=0;i<4;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase1))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}for(i=0;i<3;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase2))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}for(i=0;i<3;i++){int fun_addr=*((reinterpret_cast<int*>(VT_addrofBase3))+i);pfun=reinterpret_cast<Fun>(fun_addr);pfun();}}

 

2. Output

 

3. Memory organization form

4. Runtime polymorphism

Derive D; base1 * b1 = & D; base1 * b2 = & D; base1 * B3 = & D; B1-> F (); // call derive: F () b2-> F (); // call derive: F () B3-> F (); // call derive: F () B1-> G () // call base1: G () B2-> G () // call base2: G () B3-> G () // call base3: G ()

 

9. Security of VT-access the virtual functions of the derived class through the pointer of the base class

1. Instance

 

#include <iostream>using namespace std;class Base{public:virtual void f(){cout<<"Base::f()"<<endl;}};class Derive:public Base{public:virtual void f1(){cout<<"Derive::f1()"<<endl;}};void main(){

Derive d;

      Base *b=&d;

      b->f1();}

2. Output

Compiler error: Error c2039: 'f1': is not a member of 'base'

3. Access through pointers at runtime

Typedef void (* Fun) (void); // fun indicates the pointer type to the void F (void) function fun pfun = 0; derive D; int vt_addr = * (reinterpret_cast <int *> (& D); // address of the virtual table int fun_addr = * (reinterpret_cast <int *> (vt_addr )) + 1); pfun = reinterpret_cast <fun> (fun_addr); pfun ();

4. Output

 

10. Security of VT-access non-public virtual function members of the base class

1. Instance

# Include <iostream> using namespace STD; class base {PRIVATE: Virtual void F () {cout <"base: F ()" <Endl ;}}; class derive: public base {public :}; void main () {typedef void (* Fun) (void); // fun indicates pointing to void F (void) function pointer type fun pfun = 0; derive D; int vt_addr = * (reinterpret_cast <int *> (& D )); // virtual table address int fun_addr = * (reinterpret_cast <int *> (vt_addr); pfun = reinterpret_cast <fun> (fun_addr); pfun ();}

 

2. Output

 

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.