含有虚函数的内存布局
来源:互联网 发布:百度大数据实验室 编辑:程序博客网 时间: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
- 含有虚函数的内存布局
- 含有虚函数多重继承派生类内存布局
- 虚函数的 内存布局
- 虚函数的内存布局(上)
- 虚函数的内存布局(下)
- C++ 虚函数内存布局
- C++ 虚函数内存布局
- C++虚函数内存布局
- c++虚函数、内存布局
- 含有object对象的布局
- 虚函数表的指针的内存布局
- C++ 虚函数和多重继承的内存布局初探
- 虚拟继承与虚函数继承的内存布局
- 类对象中虚函数表指针的内存布局
- 有虚函数,虚拟继承时对象的内存布局
- 含有虚函数的类sizeof大小
- 含有虚函数的类sizeof大小
- 含有纯虚函数的例子
- is_executable 判断给定的文件名是否是可执行的文件
- 黑马程序员----Java 反射内省泛型
- SQL Server 排名函数
- Android中Uri的使用
- 6-0. 混合类型数据格式化输入(5)
- 含有虚函数的内存布局
- TCP/UDP Socket编程步骤
- oracle之给表、列添加注释以及读取注释
- 测试
- 初学python之input函数
- git详解之二----git 基础
- 广东高考录取分数线出炉 考生12点后可查高考成绩
- C++杂记: 内联函数的使用,与宏定义、成员函数区别
- OpenStack Heat服务介绍 (二)