Concept:
Virtual functions (virtual function) are implemented by a virtual function table (virtual table), referred to as v-table.
The role of learning virtual functions:
Understand the mechanism of C + + to implement polymorphism, solve the problem of inheritance and coverage.
The following excerpt from: Http://www.cppblog.com/xczhang/archive/2008/01/20/41508.html General Inheritance (no virtual function overrides)
Next, let's look at what the virtual function table is like when inheriting. Suppose you have an inheritance relationship as shown below:
Note that in this inheritance relationship, subclasses do not have functions that overload any of the parent classes. Then, in an instance of a derived class, its virtual function table looks like this:
For example: derive D; The virtual function table is as follows:
We can see the following points:
1 virtual functions are placed in the table in the order in which they are declared.
2 The virtual function of the parent class is in front of the virtual function of the subclass.
I believe that smart you can certainly refer to the previous program, to write a program to verify. General inheritance (with virtual function overrides)
It is obvious that the virtual function of the parent class is overridden, otherwise the virtual function becomes meaningless. Next, let's take a look at what it would look like if a virtual function in a subclass overloaded the virtual function of the parent class. Suppose we have one of these inheritance relationships.
In order for you to see the effect of being inherited, in the design of this class, I covered only one function of the parent class: F (). Then, for an instance of a derived class, its virtual function table would look something like the following:
We can see the following points from the table,
1 the covering F () function is placed in the position of the original parent virtual function in the virtual table.
2 functions that are not covered are still.
In this way, we can see that for programs like the following,
Base *b = new Derive ();
B->f ();
The position of the F () of the virtual function table in the memory of B is already replaced by the Derive::f () function address, so the derive::f () is invoked when the actual call occurs. This enables polymorphism. Multiple inheritance (no virtual function overrides)
Next, let's look at the situation in multiple inheritance, assuming that there is an inheritance relationship for the following class. Note: Subclasses do not have functions that overwrite the parent class.
For a virtual function table in a subclass instance, the following looks like this:
We can see:
1 each parent class has its own virtual table.
2 The member function of the subclass is placed in the table of the first parent class. (The so-called first parent class is judged in the Order of Declaration)
This is done in order to solve the different parent class type of pointer to the same subclass instance, and can call to the actual function. multiple inheritance (with virtual function overrides)
Let's take a look at the case where a virtual function overlay occurs.
In the following illustration, we overwrite the F () function of the parent class in the subclass.
The following is a diagram of a virtual function table in a subclass instance:
We can see that the position of F () in the three parent class virtual function table is replaced by the function pointer of the subclass. In this way, we can point to a subclass of the parent class of any static type and call the subclass's F (). Such as:
Derive D;
Base1 *B1 = &d;
Base2 *b2 = &d;
Base3 *b3 = &d;
B1->f (); Derive::f ()
B2->f (); Derive::f ()
B3->f (); Derive::f ()
B1->g (); Base1::g ()
B2->g (); Base2::g ()
B3->g (); Base3::g () security
Every time you write a C + + article, you always have to criticize C + +. This article is no exception. Through the above, I believe we have a more detailed understanding of the virtual function table. Water may carry a boat, and it can also overturn. Now, let's see if we can do something bad with a virtual function table.
one, accessing a subclass's own virtual function through a pointer to a parent type
We know that it is meaningless for subclasses not to overload the virtual functions of the parent class. Because polymorphism is also based on a function overload. Although in the above diagram we can see that there are derive virtual functions in the BASE1 virtual table, we simply cannot use the following statement to invoke the subclass's own virtual function:
Base1 *b1 = new Derive ();
B1->F1 (); Compilation error
Any attempt to use a parent class pointer to invoke a member function in a subclass that does not overwrite the parent class is considered illegal by the compiler, so that such a program cannot be compiled at all. But at run time, we can access the virtual function table through the way of pointer to violate C + + semantics behavior. (For this attempt, read the code in the appendix below and believe you can do it)
Ii. visit to Non-public the virtual function
In addition, if the virtual functions of the parent class are private or protected, but these are not public virtual functions will also exist in the virtual function table, so we can also access the virtual function table to access these non-public virtual functions, this is very easy to do.
Such as:
Class Base {
Private
virtual void F () {cout << "base::f" << Endl;}
};
Class Derive:public base{
};
typedef void (*fun) (void);
void Main () {
Derive D;
Fun Pfun = (Fun) * ((int*) * (int*) (&d) +0);
Pfun ();
}