c++类成员变量的内存分配以及另类技巧
这是自己的学习笔记;
成员变量的内存分配;
有几点要知道:
静态成员不占用对象空间;
成员函数不占用对象空间;
构造函数不占用对象空间;
析构函数不占用对象空间;
虚函数不直接占用对象空间;
如果类的成员中含有虚函数,那么会在对象内存的开始位置添加一个指向虚函数表的指针;
该虚函数表的大小与虚函数的数量无关;
虚函数无论被继承多少次,依旧是虚函数;
如果该类是由其他类派生而来,那么该类对象的大小除要包含该类所有成员变量大小外,还应包含基类的成员变量大小;
如果基类包含虚函数,那么派生出来的类对象也应该包含一个虚函数表指针;
所有内存占用应遵循内存对其的原则;
先看下面代码:
- C/C++ code
#include<iostream>using namespace std;class A{private:int b;public:int c;void outthis(){cout<<"对象本身的地址:"<<this<<endl;}void outa(){cout<<"成员变量a的地址:"<<&this->a<<endl;}void outb(){cout<<"成员变量b的地址:"<<&this->b<<endl;}void outc(){cout<<"成员变量c的地址:"<<&this->c<<endl;}private:int a;};int main(){A s;s.outthis();s.outa();s.outb();s.outc();system("pause");return 0;}运行结果如下:
这里可以看到,普通数据成员的内存分配顺序,是按照声明变量的顺序来排序的,跟共有私有无关;
当我们试图在类外访问对象的私有数据时,会提示无法访问;
有没有一种方法绕过这种限制呢?
这里我们看到可以通过一些其他手段访问私有数据;
有人问了 如果有多个私有数据怎么访问?
综合上面的知识,把代码做了如下修改,再看结果:
可以看到,我们通过其他手段还是能够绕过私有数据的权限进行访问的;
详解一下:
声明变量s后,调用构造函数给s的三个成员a,b,c变量赋值55,66,77;
这时s内部的结构为:
我们前面证明了,在没有其他情况的前提下(比如虚函数需要在开始位置添加一个指向虚函数表的指针);
s的地址就是第一个成员的地址;
所以 &s就是变量c的地址;但是这个地址的类型为A*;我们还要把它转化为int*型,才可以对其进行正常读取;
所以得到*(int*)&s;
然后再看a;
先要得到他的地址; a的地址相对于后移了sizeof(int)个字节;
(char*)&s+sizeof(int)这样就得到他的地址了;
然后跟c一样转换类型再取值,就象这样:*(int*)((char*)&s+sizeof(int))
有人要问:为什么先把&s转化为char*类型?
看下面例子:
int a;
int*p=&a;
假设此时p值为0x00000010
那么p+1呢?是0x00000011吗?
不是的;应该是0x00000014;
p+1相当于p+sizeof(int);
也就是他的一个的偏移量是他所存放的数据类型的内存占用量;
所以我们先临时从A*类型转换为char*类型,让&s+sizeof(int)时表示内存地址+sizeof(char)*sizeof(int);而不是+sizeof(A)*sizeof(int);
然后b的取值方法就类似了,只不过他是便宜两个int的大小而已;
好了就这点东西吧.
[解决办法]
额,其实指针的大小是由可寻址范围决定的....
[解决办法]
图片挂了