C++程序运行时内存布局之----------无继承情况下的虚函数
来源:互联网 发布:淘宝付款时间限制 编辑:程序博客网 时间:2024/04/30 16:07
本文转自 http://blog.csdn.net/smstong/article/details/6584026
虚函数是C++实现多态的关键,没有虚函数,C++只能是OB,不能完成OO。对于VC++中虚函数的实现机制,有很多文章,我看过的是陈浩写的,链接如下:
http://blog.csdn.net/haoel/article/details/1948051。总觉得还是有些不太清楚的,所以自己做了进一步的实验,记录下来以供参考。
本文介绍的是没有继承情况下,带有虚函数的类在内存中布局,以及其实例(对象)内存布局。
1.源码
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- class CVirtual
- {
- public:
- int x;
- public:
- virtual void VF()
- {
- cout<<this->x<<endl;
- cout<<"hello"<<endl;
- }
- public:
- CVirtual(int x)
- {
- this->x = x;
- }
- };
- typedef void (CVirtual::*Fun)();
- union
- {
- Fun f;
- unsigned int addr;
- }ut;
- int main(int argc, char** argv)
- {
- //打印出类实例的大小
- cout<<"对象大小为 :"<<sizeof(CVirtual)<<endl;
- CVirtual *p = new CVirtual(999);
- CVirtual *p1 = new CVirtual(888);
- //打印对象地址
- cout<<"新建对象的地址 :"<<p<<endl;
- //打印第一个成员变量地址
- cout<<"对象中第一个成员变量的地址 :"<<&p->x<<endl;
- //打印虚函数的地址
- ut.f = &(CVirtual::VF);
- cout<<"类中第一个虚函数的地址 :"<<std::hex<<std::showbase<<ut.addr<<endl;
- //虚表指针
- unsigned int vptr = *((unsigned int*)p);
- cout<<"对象1中虚表指针(即虚表地址)为 :"<<std::hex<<std::showbase<<vptr<<endl;
- //虚表第一项值为
- unsigned slot0 = *((unsigned int*)vptr);
- cout<<"虚表中第一项的值(第一个虚函数地址):"<<std::hex<<std::showbase<<slot0<<endl;
- //虚表指针
- unsigned int vptr1 = *((unsigned int*)p1);
- cout<<"对象2中虚表指针(即虚表地址)为 :"<<std::hex<<std::showbase<<vptr1<<endl;
- //虚表第一项值为
- unsigned slot01 = *((unsigned int*)vptr1);
- cout<<"虚表中第一项的值(第一个虚函数地址):"<<std::hex<<std::showbase<<slot01<<endl;
- //虚函数的原型
- typedef void (__thiscall *MyFun)(void* pThis);
- //调用虚函数表中的第一个函数
- MyFun f = (MyFun)slot0;
- f(p);
- //调用虚函数
- MyFun f1 = (MyFun)ut.addr;
- f1(p);
- delete p;
- delete p1;
- cin>>argc;
- }
2.结果
3.内存布局图
4.结论
- 虚函数表在编译期间已经确定,建立在data区,运行期只是把由构造函数把对象的vptr值设定为这个地址,同一个类的所有实例共享同一个虚函数表;
- 虚函数表中的每一个项目不一定是虚函数的地址,很可能是一个代理函数,然后由代理函数再调用虚函数;
- C++程序运行时内存布局之----------无继承情况下的虚函数
- C++程序运行时内存布局之----------无继承情况下的虚函数
- C++程序运行时内存布局之----------无继承情况下的虚函数
- 【C++】虚函数和虚继承的内存分布情况
- 一个C程序运行时的内存分配情况
- c/c++程序运行时的内存情况
- C/C++程序运行时进程的内存分布情况
- 在无函数声明的情况下运行时动态调用DLL函数
- 有虚函数,虚拟继承时对象的内存布局
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- C++程序运行时内存布局之----------局部变量,全局变量,静态变量,函数代码,new出来的变量
- 虚拟继承与虚函数继承的内存布局
- C++ 多继承和虚继承的内存布局
- 虚继承下的多重继承内存布局
- C++内存分布之菱形继承(无虚函数)
- C++中包含有虚函数的单继承状态下的类的内存布局
- C++中包含有虚函数的单继承状态下的类的内存布局
- oracle 自定义类型数据插入
- 学生管理系统信息查询部分主要功能总结
- 第二章 Android内核和驱动程序(转)
- weblogic10 下载
- GUI(主)线程与子线程之间的通信
- C++程序运行时内存布局之----------无继承情况下的虚函数
- Android 实战项目之五子棋 附源码
- Recommond books or blog about testing
- TTL电平与CMOS电平的区别
- js如何判断输入是否为正整数、浮点数等数字的函数
- struts convention-plugin的使用
- Java 中 Vector、ArrayList、List 使用深入剖析
- Android软件开发之ListView 详解 (六)
- MFC由CView转化为CScrollView