The virtual function table _c language behind the interface of C + + COM programming

Source: Internet
Author: User

Objective

People who learn C + + must all know polymorphic mechanisms; Polymorphism is the instance of the parent type pointing to its subclass, and then invoking the member function of the actual subclass through the pointer to the parent class. Have you ever thought about how polymorphic mechanisms are implemented? and COM in the interface to the application of this mechanism to the extreme, so, do not know the polymorphic mechanism of the people, is never able to understand the COM. Therefore, in the summary of COM, it is very necessary to specifically summarize the C + + polymorphism mechanism is how to achieve.

Polymorphic

What is polymorphism? As it is said, polymorphism is an instance of the parent type pointing to its subclass, and then the member function of the actual subclass is called through the pointer to the parent class. Now through the code, so that everyone firsthand experience of polymorphism:

Copy Code code as follows:

#include <iostream>
using namespace Std;

Class A
{
Public
void Print ()
{
cout<< "I am A." <<endl;
}
};

Class B:public A
{
Public
void Print ()
{
cout<< "I am B." <<endl;
}
};

int main ()
{
A *paobj = new B ();
Paobj->print ();
}

The result of the above code is: I am A. This is not polymorphic behavior.

Well, after the transformation of the above code, in the Class A print function before adding the keyword virtual, the specific code is as follows:

Copy Code code as follows:

#include <iostream>
using namespace Std;

Class A
{
Public
virtual void Print ()
{
cout<< "I am A." <<endl;
}
};

Class B:public A
{
Public
void Print ()
{
cout<< "I am B." <<endl;
}
};

int main ()
{
A *paobj = new B ();
Paobj->print ();
}

At this point, the code runs as follows: I am B. This time it shows a polymorphic behavior. Well, as much as I don't say, with this simple example, you can realize the concept of polymorphism. Start today's theme from below.

virtual function table

The key of polymorphic mechanism is the virtual function table, which is VTBL. When we define a class that contains a virtual function, we actually define a table of virtual functions, a class that does not have a virtual function does not contain a virtual function table, and only if the class is instantiated will the table be assigned to the memory of the instance; In this virtual function table, the address of each virtual function is stored; it's like a map, Indicates the function that should actually be called. For example, I define a class as follows:

Copy Code code as follows:

Class CIF
{
Public
CIF () {}
CIF (int i, int f): M_ivar (i), M_fvar (f) {}
virtual void IF1 () {cout<< "I ' m IF1" <<endl;}
virtual void IF2 () {cout<< "I ' m IF2" <<endl;}
virtual void IF3 () {cout<< "I ' m IF3" <<endl;}
void Memfunc () {cout<< "I ' m IF4" <<endl;}
Private
int M_ivar;
float M_fvar;
};

Such a class, when you go to define an instance of this class, the compiler assigns a member variable to the class, which points to the virtual function table, where each item in the virtual function table records the address of the corresponding virtual function, as shown in the following figure:

When the variables for this class have not been initialized, as shown in the previous illustration, the values of the variables are random values, and the corresponding virtual function addresses in the pointer __vfptr of the dummy function table are also the wrong addresses; only when we actually complete the declaration and initialization of this variable can these values be initialized correctly, as shown in the following figure:

As you can see from the image above, the elements in the __vfptr pointer to the virtual function table are given the correct virtual function value, pointing to the three virtual functions defined in the class, respectively. Also, the __vfptr pointer defines a position higher than the position of the M_ivar and M_fvar variables, and in the C + + compiler, it guarantees that the pointer to the virtual function table exists at the very beginning of the object instance, mainly for multiple inheritance or multi inheritance. Can take to this virtual function table with high performance, then traverse, look for the corresponding virtual function pointer, make corresponding call.

As we all know, virtual functions are used to support polymorphism in C + +, and a single class, with a virtual function, without any inheritance, that is, there is no subclass to overwrite the virtual function of the parent class, this is meaningless. So the following will be from various aspects of the detailed description of virtual function table.

There is no single inheritance that implements polymorphism

For example, there are the following inheritance relationships:

In this inheritance relationship, CIF2 as a subclass of CIF1, but CIF2 does not rewrite any virtual functions of the CIF1 class; the definition CIF2 if2obj; instance, in the instance of a derived class, its virtual function table should be as follows:

Copy Code code as follows:

[0] 0x011513c5 {interfacedemo2.exe! Cif1::if1 (void)} void *
[1] 0X011512CB {interfacedemo2.exe! Cif1::if2 (void)} void *
[2] 0x01151343 {interfacedemo2.exe! Cif1::if3 (void)} void *
[3] 0x01151249 {interfacedemo2.exe! Cif2::if4 (void)} void *
[4] 0x01151433 {interfacedemo2.exe! Cif2::if5 (void)} void *
[5] 0x01151267 {interfacedemo2.exe! Cif2::if6 (void)} void *
[6] 0x00000000 void *

As you can see, virtual functions are stored in the table in the order they are declared, and the virtual functions of the parent class are in front of the virtual function of the subclass.

Realization of polymorphic single inheritance

Now, in the CIF2 class, I rewrite the IF1 functions of the CIF1 class, and their relationships are as follows:

In the above illustration, CIF2 inherits the CIF1 and overrides the CIF1 virtual function IF1 in the CIF2 class, so what do we now look like in a virtual function table?

Copy Code code as follows:

[0] 0x00b61311 {interfacedemo2.exe! Cif2::if1 (void)} void *
[1] 0x00b612c6 {interfacedemo2.exe! Cif1::if2 (void)} void *
[2] 0x00b61343 {interfacedemo2.exe! Cif1::if3 (void)} void *
[3] 0x00b61249 {interfacedemo2.exe! Cif2::if4 (void)} void *
[4] 0x00b61433 {interfacedemo2.exe! Cif2::if5 (void)} void *
[5] 0x00000000 void *

What did you find out? The first item in the Virtual function table is CIF2::IF1, not cif1::if1, which shows that when the virtual function of the parent class is overridden in a subclass, the address of the new function overrides the virtual function address of the parent class, so that the function that needs to be called can be found correctly in polymorphism. , and the function that is not overwritten is stored in the virtual function table in that order.

Multi-Inheritance without polymorphism

For simple, multiple inheritance that does not implement polymorphism, for example, has one of the following multiple inheritance relationships:

If there is no virtual function overriding any of the parent classes in the subclass, what should its virtual function table look like?

virtual function table CIF1, as follows:

Copy Code code as follows:

[0] 0x001e13d9 {interfacedemo2.exe! Cif1::if1 (void)} void *
[1] 0x001e12df {interfacedemo2.exe! Cif1::if2 (void)} void *
[2] 0x001e1357 {interfacedemo2.exe! Cif1::if3 (void)} void *
[3] 0x001e10c8 {interfacedemo2.exe! Cif3::if4 (void)} void *
[4] 0x001e1041 {interfacedemo2.exe! Cif3::if5 (void)} void *
[5] 0x001e1249 {interfacedemo2.exe! Cif3::if6 (void)} void *
[6] 0x00000000 void *

virtual function table CIF2, as follows:

Copy Code code as follows:

[0] 0x001e1258 {interfacedemo2.exe! Cif2::if7 (void)} void *
[1] 0x001e1447 {interfacedemo2.exe! Cif2::if8 (void)} void *
[2] 0x001e127b {interfacedemo2.exe! Cif2::if9 (void)} void *
[3] 0x00000000 void *

From the above virtual function table, we can analyze that each parent class has its own virtual function table, and the virtual function of subclasses is placed in the table of the first parent class. The first parent class is judged in terms of the declaration order.

Multi-state multiple inheritance implementation

It says that there is no rewrite, and now it's about rewriting; for example, there are now the following:

The virtual function of the parent class is overridden in a subclass, and what does its virtual function table look like?

virtual function table CIF1, as follows:

Copy Code code as follows:

[0] 0X012013CF {interfacedemo2.exe! Cif3::if1 (void)} void *
[1] 0x012012d5 {interfacedemo2.exe! Cif1::if2 (void)} void *
[2] 0x0120134d {interfacedemo2.exe! Cif1::if3 (void)} void *
[3] 0x01201456 {interfacedemo2.exe! Cif3::if4 (void)} void *
[4] 0x012014d8 {interfacedemo2.exe! Cif3::if5 (void)} void *
[5] 0x00000000 void *

virtual function table CIF2, as follows:

Copy Code code as follows:

[0] 0x012014e2 {interfacedemo2.exe![ Thunk]:cif3::if1 ' adjustor{4} ' (void)} void *
[1] 0x012014ce {interfacedemo2.exe! Cif2::if2 (void)} void *
[2] 0x012014d3 {interfacedemo2.exe! Cif2::if3 (void)} void *
[3] 0x00000000 void *

From the above virtual function table, we can see that all the cif1::if1 (void) in the virtual function table is replaced with cif3::if1 (void), so we can call IF1 (void) with any parent class pointer, which actually calls cif3::if1 (void) , this realizes the so-called polymorphism.

Summarize

summed up so much about the contents of the virtual function table, it is very ridiculous, and the interface is not much of a relationship; however, all this is the basis of COM, com behind, is the interface, and the interface behind, which I summarized here, plainly, fully understand here, for the understanding of COM interface is very useful. I hope my summary is useful to everyone.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.