An in depth analysis of C++ polymorphism and virtual functions

  • 2020-07-21 09:13:05
  • OfStack

The reason for deriving a class is not always to inherit or add new members, but sometimes to redefine the members of the base class so that the base class members "get a new lease of life." The real power of object-oriented programming lies not only in inheritance, but also in allowing derived objects to be treated like base object 1, whose core mechanisms are polymorphism and dynamic linking.

(1) Polymorphism

Polymorphism means that the same message being received by different objects results in different behavior. A message refers to a call to a class member function, and a different behavior refers to a different implementation, that is, a different function is called.

1) Classification of polymorphism

Broadly speaking, polymorphism refers to the ability of a one-piece program to handle multiple types of objects. In C++, this polymorphism can be achieved by overloading polymorphism (function and operator overloading), forcing polymorphism (type casting), and type parameterization polymorphism (template)

, including polymorphic (inheritance and virtual functions) four ways to achieve. Type parameterized polymorphic and polymorphic included polymorphic is called 1 general polymorphism, which is used to systematically describe the semantically related 1 group of types. Overloaded polymorphism and forced polymorphism are called special polymorphism and are used to characterize semantically unrelated inter-type relationships.

In C++, virtual functions are adopted to realize the inclusion of polymorphism. Virtual functions provide a more flexible polymorphism mechanism for C++, which can only be determined when the program is running. Therefore, virtual functions are the essence of polymorphism, and classes containing at least 1 virtual function are called polymorphic classes. Inclusion polymorphism is frequently used in object-oriented programming.

2) Static linking

Linking, also known as binding, is the process of combining modules or functions to generate executable code from 1, while allocating memory addresses to each module or function and providing the correct memory addresses for external access.

Binding a function implementation to a function call at compile time is called static link-up. Static link-up must know all the information needed for the execution of functions and modules at compile time, and its selection of functions is based on the type of pointer (or reference) to the object. All linking in C is static. C++ 1 in general is also static linking.


class Point{
  public:
    void area(){cout<<"point";}
  };
  class Circle:public Point{
  public:
    void area(){cout<<"circle";}
  };
  Point a; Circle c;
  a.area();   // call a.Point::area() 
  c.area();   // call c.Circle::area() Name rules 
  Point * pc=&c,&rc=c;  // The assignment compatibility rules described in the previous article 
  pc->area();  // call pc->Point::area()
  rc.area();   // call rc.Point::area()

3) Dynamic linking

The binding of a function implementation to a function call when the program is running is called dynamic linking. For example, at compile time, if you check it only for compatibility, that is, if it conforms to the condition that the derived class object address can be assigned to a base class pointer variable. As for pc - > area() doesn't make a decision about which function to call until the program has run here. If you want it to call Circle::area(), you need to specify the area() function of the Point class as a virtual function. The definition form is:

virtual void area(){cout<<"point";}

When the compiler compiles a class that contains virtual functions, it creates a virtual function table (VTABLE) for it, which is equivalent to an array of Pointers to the entry address of each virtual function. The compiler adds or subtracts an additional data member to the class, which is a pointer to the vtable, called vptr.

If the derived class does not override the virtual function, the address that the element in the derived class's virtual function list points to is the address of the base function area(), that is, the derived class simply inherits the base class's virtual function

If the derived class rewrites the virtual function as follows:

 virtual void area() {cout<<"circle";}

Then the compiler points the elements in the derived vTABLE to Circle::area()

For objects that contain virtual functions, the compiler creates a function entry address that holds the pointer to the table, vptr, and then fills in the function pointer in the order in which virtual functions are declared in the class. When calling a virtual function, first find the virtual function table through vptr, and then find out the real address of the virtual function.

Derived classes can inherit from the base class's virtual function table, and as long as they are member functions with the same name (and with the same arguments), they automatically generate virtual functions whether or not virtual is declared. If the derived class does not overwrite the virtual function that inherited the base class, the function pointer calls the virtual function of the base class.

(2) Virtual functions

1) Virtual function definition

Virtual functions are only one member of a class and cannot be static. The virtual function is defined by adding the keyword virtual before the member function definition or declaration:


class The name of the class {
    ...
    virtual  The return type   The function name   (Formal parameter list) // Virtual functions 
    ...
  };
  class Point
  {
    virtual void area ();    // Virtual function declaration 
    virtual double volumn(){}  // Virtual function definition 
  };

Note that the virtual keyword is only used in the body of the class.

Using virtual functions allows you to define different implementations of functions using the same function name in both base and derived classes, thus achieving "one interface, many ways." When a virtual function is accessed by a base class pointer or reference, the virtual function version of the class on which the object was called is automatically determined based on the actual object to which the pointer or reference points at run time.

2) Conditions for virtual functions to realize polymorphism

The keyword virtual instructs the C++ compiler to dynamically link calls to virtual functions. This polymorphism is determined dynamically until the program runs to the corresponding statement and is called runtime polymorphism. However, the use of virtual functions does not always result in polymorphism, nor does the use of dynamic linking. For example, using a member name qualification for a virtual function in a call forces C++ to use static linking for calls to that function.

There are two conditions under which virtual functions must produce runtime polymorphism.

a) overrides the virtual function of the same name

b) USES Pointers or references according to assignment compatibility rules


Point *p=new Circle;  // The base class pointer points to the derived class 
  cout<<p->area();   // Dynamic binding 
  void fun(Point *p)
  {cout<<p->area();}   // Dynamic binding 

3) In a derived class, polymorphism occurs when a pointer to a member function of the base class points to a virtual function and accesses the virtual function through a pointer or reference to an object.


#include<iostream>
using namespace std;
class Base{
public: virtual void print(){cout<<"base"<<endl;}
};

class Derived :public Base{
public:
 void print(){cout<<"derive"<<endl;}
};

//void(Base::*pf)();
void display(Base *p,void(Base::*pf)())
{
(p->*pf)();

}

int main()
{
 Derived d;
 Base b;
 display(&d,&Base::print);
 display(&b,&Base::print);
 return 0;
}

lzb@lzb:~/classic_lib/C++_learning$ g++ 427.cpp
lzb@lzb:~/classic_lib/C++_learning$ ./a.out 
derive
base

display has two functions, the first argument being a pointer to the base class, and the second argument being a pointer to the class member function. display USES the base class pointer to call the member function to which the pointer points. Depending on the object to which the base class pointer points, the call is a virtual function of the base class or a derived class virtual function.

Supplement:

Three characteristics of object orientation: encapsulation, inheritance, and polymorphism.

What is polymorphism

Polymorphism means that one thing has many forms, the English word is polymorphism, sending the same message to different objects, and different objects will have different behaviors (methods) when receiving. That is, each object can correspond to a common message in its own way.

For example, function overloading and operator overloading are polymorphic phenomena.

One example of life, such as student of school, the headmaster release information of which 1 day 1, different objects can produce different reaction, students are ready to go to school, parents need to prepare the tuition, teachers also need to start preparing, school dining room to start shopping, this is the polymorphism, if there is no polymorphism, the principal needs to students, teachers and parents different objects such as a separate notice.

In C++, polymorphism 1 is that functions with different functions can have the same function name, which makes it possible to call functions with different contents with one function name.

From the perspective of system implementation, polymorphism falls into two categories: static polymorphism and dynamic polymorphism
Static polymorphism is realized by function overloading, while dynamic polymorphism is realized by virtual function.

What is a virtual function

In C + + virtual functions is used to solve the problem of dynamic polymorphism, the so-called virtual functions, is in the base class declaration function is virtual, is not real, then not formally define this function in a derived class, during the program is running, with a pointer to a derived class object 1, so you can call the pointer to function in a derived class object, and not call other functions in the derived class.

conclusion

Above is this site to introduce C++ polymorphism and virtual functions, I hope to help you!


Related articles: