C++类实例占用的内存结构,及虚函数表的一点探究
来源:互联网 发布:scala编程 第二版 pdf 编辑:程序博客网 时间:2024/05/12 11:36
或许编译器的差异, 所得的结果也不同, 但某些地方还是可以借鉴的.
帖子讨论:
http://topic.csdn.net/u/20110509/11/43917452-ae4d-4ba9-8c72-25e454e60e75.html?113761501
参考:
http://www.kuqin.com/language/20090314/39911.html
http://www.cse.wustl.edu/~mdeters/seminar/fall2005/mi.html
运行结果如下:
run D2CPocket::func1()
run DCPocket::func2()
run CPocket::func3()
run D2CPocket::func4()
在VC++ 6.0 和CodeBlock中用watch查看D2CPocket 的实例d2所占的内存, 大致存储顺序如下:
|--CPocket成员所占的内存
|--DCPocket成员所占的内存
|--D2CPocket成员所占的内存
即是这样的:
CPocket虚函数表
CPocket::ptr
CPocket::val
DCPocket:seq
D2CPocket::index
结论1:类实例所占内存结构是基类成员在前,派生类成员在后的顺序.
结论2:类实例中的开头4字节, 是一个指针(即虚函数表指针), 指向一个数组vtable[], 数组的每个元素是虚函数地址.
所以, (类实例开始的四字节)虚函数指针用解操作2次, 才能得到虚函数的入口地址;
还发现了一个小问题, 代码中的三个类CPocket, DCPocket, D2CPocket都是没有"虚析构函数", 如果类CPocket, DCPocket加上虚析构,再次执行代码, 会发现一些有意思的小现象, 不同编译器表现不同, 大致是虚函数被"意外"的调用了,
为什么呢? 用vc6的watch查看类实例d2的虚函数表, 发现~ vtable[0]的内容, 是虚析构函数的地址,,,
所以第一次调用
pf = (pFunc)(*p);
pf(); 的时候,调用的是派生类的虚析构函数,
结论3:如果派生类的基类中还有虚析构, 那么派生类实例的虚函数表开头是该类的析构函数.
*注,如果某类不会当做基类, 那么不必把该类的虚构声明为virtual.
- C++类实例占用的内存结构,及虚函数表的一点探究
- 对象的内存结构及占用空间的计算方法
- C++(虚)继承类的内存占用大小
- C++(虚)继承类的内存占用大小
- iOS的结构体存储内存探究
- c 语言结构中成员函数占用内存吗
- 我的C++ (三) - 空类/结构内存占用情况
- 结构体内嵌联合体的内存占用
- 虚函数的内存结构
- 虚函数的内存结构
- 内存(二)--类的实例化占用
- 内存(三)--类的实例化占用
- Oracle的实例占用内存调整
- C/C++--类占用内存的大小计算
- C/C++--类占用内存的大小计算
- cocos2d中图片和所占用内存的一点总结!
- c::关于虚函数的一点补充
- 关于内存泄露的一点实例
- linux下FAT和NTFS文件隐藏信息的获取方法
- 用c++编写简单的图书管理系统怎么弄
- android布局之LinearLayout, layout_weight
- MySQL常用命令
- 对table列表按某一列进行排序
- C++类实例占用的内存结构,及虚函数表的一点探究
- Embed外部资源后对应类的类型
- 糟糕老板6个最坏的管理方式
- Perl中的符号 ->、=> 和 :: 分别表示什么意思?
- LINUX下查看系统消息
- 键盘(键盘基础,按键消息)
- wince5.0中断分析
- 更换本地svn用户名与密码
- 类加载器