含有虚函数的内存布局

来源:互联网 发布:百度大数据实验室 编辑:程序博客网 时间:2024/06/06 02:50

http://hi.baidu.com/hj11yc/item/0428b1ba2c7e8aadeaba93b3

另外:

可参考:

http://blog.csdn.net/haoel/article/details/3081385

我们来看看有虚函数,并且是有虚基类的类的内存布局

我们看看一个有成员的例子:

#include<iostream>using namespace std;class A{public:int a;A():a(1){}virtual void show(void){cout<<"call A"<<endl;}};class B:virtual public A{public:int b;B():b(2){}virtual void show(void){cout<<"call B"<<endl;}};class C:virtual public A{public:int c;C():c(3){}virtual void show(void){cout<<"call C"<<endl;}};class D:public B,public C{public:int d;D():d(4){}virtual void show(void){cout<<"call D"<<endl;}};int main(void){D d;cout<<"the address begin:"<<&d<<endl;cout<<"////////////////////////////////////"<<endl;cout<<hex<<*(((int *)&d)+0)<<endl;cout<<hex<<*(((int *)&d)+1)<<endl;cout<<hex<<*(((int *)&d)+2)<<endl;cout<<hex<<*(((int *)&d)+3)<<endl;cout<<hex<<*(((int *)&d)+4)<<endl;cout<<hex<<*(((int *)&d)+5)<<endl;cout<<hex<<*(((int *)&d)+6)<<endl;cout<<hex<<*(((int *)&d)+7)<<endl;cout<<hex<<*(((int *)&d)+8)<<endl;cout<<hex<<*(((int *)&d)+9)<<endl;system("pause");return 1;}


输出来看看呢?

‍‍

可以看个大概是怎么分布的,但是哪些是vptr,社么是vbptr呢》》?????

来看个详细的例子

#include<iostream>using namespace std;class A{public: int a; A():a(1){} virtual void show(void){cout<<"call A"<<endl;}};class B:virtual public A{public: int b; B():b(2){} virtual void show(void){cout<<"call B"<<endl;}};class C:virtual public A{public: int c; C():c(3){} virtual void show(void){cout<<"call C"<<endl;}};class D:public B,public C{public: int d; D():d(4){} virtual void show(void){cout<<"call D"<<endl;}};typedef void (*FUN )(void);int main(void){ D d; cout<<"the address begin:"<<&d<<endl; cout<<"////////////////////////////////////"<<endl;    cout<<hex<<*(((int *)&d)+0)<< "   ";cout<<dec<<*((int *)(*((int *)&d+0))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+0))+1)<<endl; cout<<hex<<*(((int *)&d)+1)<<endl; cout<<hex<<*(((int *)&d)+2)<<"   ";cout<<dec<<*((int *)(*((int *)&d+2))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+2))+1)<<endl;//这两个都是指向virtual base table的指针,第一项都为0,第二项是偏移量 cout<<hex<<*(((int *)&d)+3)<<endl; cout<<hex<<*(((int *)&d)+4)<<endl; cout<<hex<<*(((int *)&d)+5)<<endl; cout<<hex<<*(((int *)&d)+6)<<"   ";cout<<dec<<*((int *)(*((int *)&d+6))+0)<<"   "; cout<<hex<<*(((int *)&d)+7)<<endl; cout<<hex<<*(((int *)&d)+8)<<endl; cout<<hex<<*(((int *)&d)+9)<<endl; cout<<"//////////////////////////////////////////"<<endl;      /*FUN fun11=(FUN)*((int *)(*((int *)&d+0))+0);  fun11();        fun11=(FUN)*((int *)(*((int *)&d+2))+0);  fun11();*////这两个不能运行,说明没有指向函数,则说明类中的第一个,第三个数据是指向基类的指针。并且在上面的输出中可以看到这两个指针的第一项都为0,说明没有虚函数,这个没有虚函数说的是没有自己独特于基类的虚函数。所以第一项为0,第二项为偏移量。  FUN fun11=(FUN)*((int *)(*((int *)&d+6))+0);  fun11();  /*fun11=(FUN)*((int *)(*((int *)&d+6))+1);  fun11();*///这个也不能,因为只有一个虚函数,并且是三个共用的,所以上面一个能运行,这个不能 system("pause"); return 1;}

看看结果:

‍‍  

可以看到什么问题么??看看我嗦分析的。也许你看到注释分析的过后会问,B,C的vptr呢?因为他们没有自己的虚函数,所以没有产生,只有vbptr,是偏移量。所以都指向了基类的vptr处。

如果不相信,你可以为B单独添加一个虚函数,然后你就知道了。不信来看看:

#include<iostream>using namespace std;class A{public:int a;A():a(1){}virtual void show(void){cout<<"call A"<<endl;}};class B:virtual public A{public:int b;B():b(2){}virtual void show(void){cout<<"call B"<<endl;}virtual void go(void){cout<<"call B:;go"<<endl;}};class C:virtual public A{public:int c;C():c(3){}virtual void show(void){cout<<"call C"<<endl;}};class D:public B,public C{public:int d;D():d(4){}virtual void show(void){cout<<"call D"<<endl;}};typedef void (*FUN )(void);int main(void){D d;cout<<"the address begin:"<<&d<<endl;cout<<"////////////////////////////////////"<<endl;cout<<hex<<*(((int *)&d)+0)<< endl;cout<<hex<<*(((int *)&d)+1)<<"   ";cout<<dec<<*((int *)(*((int *)&d+1))+0)<<"   ";cout<<dec<<*((int *)(*((int *)&d+1))+1)<<endl;cout<<hex<<*(((int *)&d)+2)<<endl;cout<<hex<<*(((int *)&d)+3)<<endl;cout<<hex<<*(((int *)&d)+4)<<endl;cout<<hex<<*(((int *)&d)+5)<<endl;cout<<hex<<*(((int *)&d)+6)<<endl;cout<<hex<<*(((int *)&d)+7)<<endl;cout<<hex<<*(((int *)&d)+8)<<endl;cout<<hex<<*(((int *)&d)+9)<<endl;cout<<"//////////////////////////////////////////"<<endl;FUN fun11=(FUN)*((int *)(*((int *)&d+0))+0);fun11();system("pause");return 1;}


我只为B增加了一个自己的虚函数,看看输出呢?


再解释下-4的含义,意思就是说有自己的虚函数,如果没有的话,这个值是0;24是偏移量,记住,基类偏移量

0 0
原创粉丝点击