The dynamic and static correlation and virtual destructor of C++ are briefly explained

  • 2020-05-05 11:34:04
  • OfStack

C++ static association and dynamic association, how does C++ achieve polymorphism of
In real life, there are many examples of polymorphism. Let's analyze how people deal with polymorphism. University freshman admission people, for instance, in learning, have a worker first review material, it was his duty to identify qualifications, then according to the specified on the admission notice, admission system and professional, transfer material to relevant departments and programs, go through the formalities for registration study of specific, different departments can also be seen as call processing program admission formalities. In the eyes of the students, this staff member is the general population, and all new students have to go through him. Students get a uniform letter of admission, but actually belong to different departments, to go through different registration procedures, this is polymorphic. So what does the worker do with polymorphism? Why distribute it to which department? It is according to a letter on the letter of admission (you were admitted to the school of xx major). So, you have to have information to distinguish, or you can't distinguish.

Again, the compilation system makes decisions about calls to functions of the same name based on the information available. For example, function overloading, the system is based on the number of parameters and different types to find the function to match. For calling virtual functions in the same class family, you should tell the compiler in a certain way which class object you are calling the function in. For example, you can provide object names directly, such as studl.display () or grad1.display (). In this way, the compilation system can determine which class object functions are called when the program is compiled.

The process of determining the specific object to invoke is called an association (binding). binding means to bind or join, to bind (or join) two things together. In this case, a function name is tied to a class object to establish an association. In general, association refers to associating an identifier with a storage address. In a computer dictionary, you can see the process by which different parts of a computer program are connected to each other. Some books translate binding as binding, binding, binding, or both. The author thinks: from the meaning, the correlation is more accurate, easy to understand. But some tutorials use the term linkage. When you see this noun, you should know that it refers to the relation described in this section.

By the way, as an aside, most of the terms in the field of computers are translated from foreign languages. But others are puzzling or even inexact. For example, in some books about computer languages, project is translated as "project". Some books about computer applications are filled with a lot of jargon. At first it sounds like a lot of jargon and it is difficult to understand. This problem has become an obstacle for many people to learn C++. Therefore, we should advocate an easy - to - understand method to clarify complex concepts. In fact, there are a lot of seemingly esoteric concepts and terms that are easy to break through. It is suggested that readers should not get bogged down in the literal interpretation of terms, but master their spiritual essence and application methods.

Note: compared with other programming languages, such as Java, C#, C++ grammar is the most abundant and flexible, is also the most difficult to master, you should step by step, do not ask for quick, in the practice of programming constantly read and memory.

The previously mentioned function overloading and virtual functions called by object names can determine at compile time which class the virtual functions they call belong to. The process is called static association (static binding), which is also called early association (early binding) because it is associated before running. Function overloads are static associations.

How does the system determine the association when the virtual function is called without specifying the object name? As you can see, polymorphism is achieved by combining base class Pointers with virtual functions. A pointer to a base class is defined to point to the corresponding class object, and then a virtual function (e.g. "pt->") is called from this base class pointer display () "). Obviously, with such a call, the compilation system cannot determine which class object's virtual function to call when compiling the line. Because compilations only do static syntax checks, the light comes from the statement form (for example, "pt-> display ();" ) is impossible to determine the calling object.

In this case, the compilation system processes it in the runtime, where it determines the association. At run time, the base class pointer variable first points to a class object and then calls the function in the object through the pointer variable. Which object's function is called at this point is definitely determined. For example, point pt to grad1 and then "pt->" display() ", of course, calls the display function in grad1. Since virtual functions are "bound" to class objects at run time, this process is called dynamic association (dynamic binding). This polymorphism is a dynamic polymorphism, that is, a run-time polymorphism.

At run time, Pointers can point to different class objects in succession, thus calling virtual functions of different classes in the same class family. Because dynamic correlation occurs at the run stage after compilation, it is also called a lag correlation (late binding).


C++ virtual destructor details
When an object of a derived class is revoked from memory, the destructor of the derived class is usually called first and then the destructor of the base class. However, if a temporary object is created with the new operator, if there is a destructor in the base class and a pointer variable is defined to that base class. When a program withdraws an object with the delete operator with pointer arguments, a situation occurs in which the system executes only the destructor of the base class and not the destructor of the derived class.

The execution of a base class with a non-virtual destructor. To simplify the process, list only the most essential parts.


#include <iostream>
using namespace std;
class Point // Define a base class Point class 
{
public:
  Point( ){} //Point Class constructor 
  ~Point(){cout<<"executing Point destructor"<<endl;} //Point Class destructor 
};
class Circle:public Point // Define derived classes Circle class 
{
public:
  Circle( ){} //Circle Class constructor 
  ~Circle( ){cout<<"executing Circle destructor"<<endl;} //Circle Class destructor 
private:
  int radius;
};
int main( )
{
  Point *p=new Circle; // with new Open up dynamic storage space 
  delete p; // with delete Free up dynamic storage 
  return 0;
}

This is just a schematic procedure. p is a pointer variable pointing to the base class, pointing to the dynamic storage space created by new, hoping to release the space pointed to by p with detele. But the result is:


executing Point destructor

Means that only the destructor of the base class Point is executed, not the destructor of the derived class Circle.

If you want to execute the destructor of the derived class Circle, you can declare the destructor of the base class as a virtual destructor, such as


  virtual ~Point(){cout<< " executing Point destructor " <<endl;}

Run the program with the rest of the program unchanged, and the result is:


executing Circle destructor
executing Point destructor

First, the destructor of derived class is called, and then the destructor of base class is called.

When the destructor of the base class is a virtual function, no matter which class object the pointer refers to in the same class family, the system will adopt dynamic correlation and call the corresponding destructor to clean up the object.

When the destructor of a base class is declared virtual, the destructor of all derived classes derived from that base class automatically becomes virtual, even if the destructor of the derived class has a different name than the destructor of the base class.

It is best to declare the destructor of a base class as a virtual function. This will automatically make the destructors of all derived classes virtual. Thus, if the program explicitly USES the delete operator to delete an object, and the operator object of the delete operator USES a base class pointer to a derived class object, the destructor of the corresponding class is called.

The concept and use of virtual destructors is simple, but it is an important technique in object-oriented programming.

It is common practice for professionals to declare virtual destructors, explicitly defining a virtual destructor whose body is empty, even if the base class does not require a destructor, to ensure proper handling when undoing dynamic allocation.

Constructors cannot be declared virtual. This is because the class object has not yet completed the creation process when the constructor is executed, and certainly not the binding of the function to the class object.


Related articles: