The basic idea of object-oriented programming is to use a program to simulate the world, which makes its various fundamental features very user-friendly, such as encapsulation, inheritance, polymorphism, etc, the virtual function is the main implementation of polymorphism in c ++. To realize polymorphism, the c ++ compiler also provides the feature of Dynamic Association or late bundling.
Virtual functions are also the key to mfc programming. There are two main methods for mfc programming: one is to respond to various messages for corresponding message processing. Second, reload and rewrite virtual functions to meet certain requirements or change some default processing of the system.
The role of a virtual function is so important. It is very helpful for us to understand and understand it. Let me hear it.
Implementation Process Analysis of polymorphism and Dynamic Association
I. Basics
1. Polymorphism: Use the pointer of the base class to dynamically call the features of functions in its derived class.
2. Dynamic Association: in the running stage, the function call is connected to the corresponding function body, also known as runtime association or late binding.
Ii. process description
1. the compiler finds that there is a virtual function in a class, and the compiler will immediately generate a virtual function table for this class followed by an analysis of the vtable ). Each table item in the virtual function table is a pointer to the corresponding virtual function.
2. the compiler implicitly inserts a pointer in this class. For the vc compiler, the pointer is inserted in the first position of the class ).
There is a way for you to perceive the existence of this implicit pointer, although you cannot directly see it in the class, however, you can compare the class size when there is a virtual function and the class size when there is no virtual function. You can find that this pointer does exist.
class cnovirtualfun{private:long lmember;public:long getmembervalue);} class chavevirtualfun{private:long lmember;public:virtual long getmembervalue);} cnovirtualfun obj;sizeof(obj) -> == 4; chavevirtualfun obj;sizeof(obj) -> == 8; |
3. When calling such constructor, In the constructor of the class, the compiler will implicitly execute the code associated with vptr and vtable, and direct vptr to the corresponding vtable. This associates the class with the vtable of this class.
4. When calling the class constructor, the pointer to the base class has now become the this pointer to the specific class, so that the correct vtable can be obtained by using this pointer, this achieves polymorphism. In this case, we can truly connect to the function body, which is dynamic Association.
Iii. vtable Analysis
Analysis 1: The virtual function table contains the addresses of all the virtual functions of this class and its parent class. If it does not reload the virtual function of the parent class, the corresponding table item in vtable points to this function of the parent class. Otherwise, point to the function after the overload.
Analysis 2: After a virtual function is inherited, it is still a virtual function. The virtual function is strictly ordered in the vtable according to the order in which it appears. Therefore, the determined virtual function corresponds to a fixed position n in the vtable, n is a constant determined during compilation. Therefore, add the corresponding n to vptr to obtain the corresponding function entry address.
Iv. assembly code for the compiler to call a virtual function
Push funparam;First, pressure the function parameter Stack
Push si;Press this pointer to the stack to ensure that the operation is performed on the current class.
Mov bx, Word ptr [si];Because the vc ++ compiler places vptr in the first position of the class
Call word ptr [bx + n];Call a virtual function. N = Location of the called virtual function in the corresponding vtable
Pure virtual functions
I. Reasons for introduction
1. To facilitate the use of polymorphism, we often need to define virtual functions in the base class.
2. In many cases, it is unreasonable for the base class to generate objects. For example, an animal can be derived from sub-classes such as tigers and peacocks as a base class, but the object generated by the animal itself is obviously unreasonable.
To solve the above problem, the concept of pure virtual function is introduced, and the function is defined as a pure virtual function method: virtual returntype function () = 0 ;), the compiler requires that the class must be overloaded to implement polymorphism. Classes that contain pure virtual functions are called abstract classes and cannot generate objects. In this way, the above two problems are well solved.
Ii. essence of pure virtual functions
1. If the class contains pure virtual functions, its vtable table is incomplete and there is a blank space. Therefore, the compiler cannot generate an object and it is absolutely not allowed to call a function that does not exist ). In its derived class, unless this function is reloaded, The vtable table of this derived class is also incomplete and the object cannot be generated, that is, it also becomes a pure virtual base class.
Virtual functions and constructor
1. constructor itself cannot be a virtual function, and virtual functions that do not work in constructor will only call its local version ).
Think about it. Using the virtual mechanism in the base class constructor may call the subclass. At this time, the subclass has not yet been generated. What are the consequences !?.
2. The Destructor itself often requires virtual functions, but the virtual mechanism does not work in the destructor.
If a virtual function is used in the class, the Destructor must be a virtual function. For example, if a virtual mechanism is used to call delete, there is no virtual destructor, how can we ensure that the delete object is the object you want to delete.
The virtual mechanism cannot take effect in the destructor, because it may cause the issue of calling virtual functions of classes that have been deleted.
Object Slicing
When the child class is mapped to the parent class, the vtable of the Child class is completely changed to the vtable of the parent class. This is the object slice.
Cause: When ing up, the interface will narrow down, And the compiler absolutely cannot call a function that does not exist. Therefore, the portal of the new derived virtual function in the subclass is forcibly cut out in the vtable.
Disadvantages of using virtual functions
There are a lot of advantages. Now let's talk about the disadvantages. The main disadvantage of virtual functions is that the execution efficiency is low. Let's take a look at the implementation process of polymorphism caused by virtual functions, and you will be able to understand the reasons.
- Analysis on the Structure of C ++ standard header files
- Concise Analysis of the C/C ++ Memory Allocation Solution
- Discuss the "dynamic" and "static" of C ++ Polymorphism"