面试---内存偏移
来源:互联网 发布:桌面软件开发架构 编辑:程序博客网 时间:2024/06/06 01:12
下面程序中pb->func();的输出结果?
#include <iostream>#include<stdio.h>using namespace std;class M{public: M() {a = 1; b = 2;}; ~M() {}; void func() { cout<<a<<" "<<b<<endl; }//private: int a; int b;};class N{public: N() {c = 3;}; ~N() {}; void func() { cout<<c<<endl; }//private: int c;};int main(){ M m; N *pb = (N*) (&m); //!!!!!!!!!!!! pb->func(); cout<<"################"<<endl; cout<<&m<<endl; cout<<(&m.a)<<endl; cout<<pb<<endl; cout<<"################"<<endl; printf("%p\n", &M::a);//%p 格式转为指针,输出地址 printf("%p\n", &M::b); printf("%p\n", &N::c); cout<<"################"<<endl; return 0;}
结果:
1################0x28ff040x28ff040x28ff04################000000000000000400000000################Process returned 0 (0x0) execution time : 0.173 sPress any key to continue.
暂且不讨论该程序设计有多么糟糕,但程序主要考察关于类对象成员调用的机制,关于这方面,在《深入理解C++对象模型》中有详解。
这里主要涉及到两方面:一是对象调用成员函数时会将调用对象与函数绑定;二是对象访问成员是根据该成员距离对象的偏移量来访问的!!!!,而不是根据成员名来访问,所谓偏移量,就是告诉你一个特定的成员位置距离对象的起点有多少个字节。
上面程序,内存中实例化了一个M类对象,然后将该地址强制转换成一个N类地址,即将该对象的地址内容强制看成一个N类对象。pb为N类的指针,理所当然调用的是N类中的fun()函数(可以跟多态的情形相比较),当调用fun()函数时,调用对象与该函数进行绑定,即fun()函数中隐含的形参this指针初始化为调用对象(M类对象)的地址,假设为0xff80。然后fun()函数打印值c。这里要注意,对象在访问类成员时,编译器并没有存储该对象各个成员的实际地址,而是存储了其相对于当前对象首地址的偏移量,由于N类只有一个成员c,在编译阶段,编译器就记录了c对于N类对象的偏移量为0,故访问c时,便是访问当前对象地址this+偏移量0,注意,this在这里绑定的是M类对象的首地址,在M类中,偏移量为0的成员是a,故打印出a的值。
关于类成员偏移量的输出,可以用程序验证。
例如如下程序:将地址0强制转换为A类对象的地址,那么打印类成员m_a和m_b的地址便是他们的偏移量,如下分别输出0,0x4。
cout<<&((M*)0)->a<<endl;cout<<&((M*)0)->b<<endl;
关于成员指针!!!!
成员指针只是记录一个成员的偏移量,而非地址,因为类中没有地址,选择一个类的成员只是意味着在类中偏移,只有把这个偏移和具体对象的首地址结合,才能得到实际地址。
成员指针并不指向一个具体的内存位置,它指向的是一个类的特定成员,而不是指向一个特定对象的特定成员,最直接的理解是将其理解为一个偏移量。这个偏移量适用于某一类A的任何对象,换言之,如果一个A类对象的成员a距离起点的偏移量是4,那么任何其他A类对象中,a的偏移都是4字节。
啰嗦一大堆,总结一下就是两句话:
类对象访问其成员时,是根据该成员在类中的偏移量来访问的。类成员指针,可以理解为指向类数据成员的一个偏移量,而非地址。
参考:http://blog.csdn.net/wenhai_zh/article/details/10311335
- 面试---内存偏移
- 类的内存偏移
- 指针内存偏移
- 内存偏移与文件偏移相互转换
- 关于内存偏移的问题
- PE内存偏移与文件偏移相互转换
- 内存偏移(RVA)与文件偏移(offset)相互转换
- win32驱动开发中的内存偏移问题
- Delphi XE2读取内存偏移数据代码
- C/C++内存偏移量学习笔记
- 用宏求结构体的内存偏移地址
- C语言中内存偏移量
- VCL对象内存分布之偏移常量
- 计算结构体内成员的内存偏移量
- 共享内存区一定要使用偏移量,而非指针!
- 关于内存对齐以及通过偏移获得结构地址
- Delphi XE2读取游戏内存偏移数据代码
- 如何使用宏求结构体的内存偏移地址
- 浏览器兼容、CSS3 选择器
- GOF23 设计模式之 适配器模式
- 【转载,细致】New与malloc的区别
- 软件测试
- Git学习笔记(一)
- 面试---内存偏移
- Datatables笔记
- java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition
- 测试
- hdu5491 The Next(合肥网赛)
- JavaScript高级程序设计之面向对象的程序设计之继承之原型链 第6.3.1讲笔记
- 【bzoj2326】【HNOI2011】【数学作业】【矩阵乘法】
- hdu5491求二进制比一个数大的数
- python : defaultdict