polymorphism
Polymorphism is one of the important features of object-oriented programming. The literal meaning can be simply understood as: multiple forms, multiple appearances. In fact, the essential meaning is the same. In object-oriented programming, it means that the same method will have different execution effects when executed by different objects.
Specifically, the implementation of polymorphism can be divided into two types: compile-time polymorphism and run-time polymorphism. The former is the specific operation process that is determined when compiling, and the latter is the operation process that is only determined during the running of the program. This determination of the operation process is binding , also known as binding .
The binding that is confirmed during compilation and connection is called static binding . The function overloading and instantiation of function templates we learned earlier fall into this category. The other is to confirm which piece of code is executed when it is running, which is called dynamic binding . In this case, it is not possible to confirm which piece of code is executed when compiling, but can only be confirmed after the program is run.
Comparing the two, static binding has already determined how to execute it during compilation, so it is efficient in execution; while dynamic binding must be slower, but its advantage is flexibility. Both have their own merits and different usage scenarios.
Below, we will give you a simple example around static linking:
/************************************//Des: C++ tutorial demo//Author: Huang//Copyright:www.dotcpp.com//Date:2017/12/20************************************ *******/#include<iostream>usingnamespacestd;#definePI3.1415926classPoint{private:intx,y;public:Point(intx=0,inty=0){this->x=x;this->y =y;}doublearea(){return0.0;}};classCircle:publicPoint{private:intr;public:Circle(intx,inty,intR):Point(x,y){r=R;}doublearea(){ returnPI*r*r;}};intmain(){PointA(10,10);cout<<A.area()<<endl;CircleB(10,10,20);cout<<B.area()< <endl;Point*p;p=&B;cout<<p->area()<<endl;Point&pp=B;cout<<pp.area()<<endl;return0;}
Two classes are defined, a dot class and a derived circle class. You can see the code of the main function and the four output area results. The results are as follows:
You can compare the code to understand the four outputs:
The first cout outputs the area of A, which is the area method in the Point class. The area is 0, so there is no problem.
The second cout outputs the area of B, which is obviously the area method of the derived class Circle. The area is naturally calculated according to the formula and the value is 1256.64, which is no problem.
The third cout outputs the area method of the Circle class object pointed to by the Point type pointer p. It outputs 0, which is obviously the area method in the Point class. What C++ implements here is static binding, that is, when compiling, it determines which area to execute based on the type of p, so it is 0.
The fourth type of cout works in the same way. It assigns a Circle type object to a Point type reference. C++ also performs static binding and also outputs 0.
Obviously, this is not the result we expect. In fact, for pointers and references, we prefer to execute the methods of the actual objects, rather than blindly determining the types of pointers and references. This is the problem if written like this. .
If you want to meet our requirements, no matter what type the pointer or reference is, it should be flexibly decided based on the actual object pointed to. Then we need to change this default static binding method and use dynamic binding, that is, flexibly decided at runtime.
In the next section, virtual functions will be explained in detail for everyone!