静态成员不占用对象空间;
成员函数不占用对象空间;
构造函数不占用对象空间;
析构函数不占用对象空间;
虚函数不直接占用对象空间;
如果类的成员中含有虚函数,那么会在对象内存的开始位置添加一个指向虚函数表的指针;
该虚函数表的大小与虚函数的数量无关;
虚函数无论被继承多少次,依旧是虚函数;
如果该类是由其他类派生而来,那么该类对象的大小除要包含该类所有成员变量大小外,还应包含基类的成员变量大小;
如果基类包含虚函数,那么派生出来的类对象也应该包含一个虚函数表指针;
所有内存占用应遵循内存对其的原则;
先看下面代码:
运行结果如下:
[img=http://b97.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/B2jOZUWjjqr.Ak2uVl76fQRB6qooUUwRzHWcZEJ2x60!/b/Yfa82zlFcAAAYtMm1zm2cAAA][/img]
这里可以看到,普通数据成员的内存分配顺序,是按照声明变量的顺序来排序的,跟共有私有无关;
[img=http://b99.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/U1fipFp4ZxGz6KC71C.rql*tdQxD1h2z8w3NsVEyBK4!/b/YSVOCDvBbwAAYljMBjs8bgAA][/img]
当我们试图在类外访问对象的私有数据时,会提示无法访问;
有没有一种方法绕过这种限制呢?
[img=http://b100.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/NEBcJHAGOPGQ.bW2vIcJ0zM6st.2*rbL3ngLYWj2npE!/b/YYYysDsLVAAAYsTpoDuFUwAA][/img]
这里我们看到可以通过一些其他手段访问私有数据;
有人问了 如果有多个私有数据怎么访问?
综合上面的知识,把代码做了如下修改,再看结果:
[img=http://b102.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/7n4dmQalAUDq1Zztjy8KYh1dBVaKl2ES*Y3pBZiJiIE!/b/YTWm0zz.JwAAYle22Ty5JwAA][/img]
可以看到,我们通过其他手段还是能够绕过私有数据的权限进行访问的;
详解一下:
声明变量s后,调用构造函数给s的三个成员a,b,c变量赋值55,66,77;
这时s内部的结构为:
[img=http://b104.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/0yIfQTSbYJuB8Xkc1f2UuSTMhsG4fLvWH3PrxvvcoRw!/b/YW9OAz5MJwAAYjnXBz4uJwAA][/img]
我们前面证明了,在没有其他情况的前提下(比如虚函数需要在开始位置添加一个指向虚函数表的指针);
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的大小而已;
好了就这点东西吧.
成员函数不占用对象空间;
构造函数不占用对象空间;
析构函数不占用对象空间;
虚函数不直接占用对象空间;
如果类的成员中含有虚函数,那么会在对象内存的开始位置添加一个指向虚函数表的指针;
该虚函数表的大小与虚函数的数量无关;
虚函数无论被继承多少次,依旧是虚函数;
如果该类是由其他类派生而来,那么该类对象的大小除要包含该类所有成员变量大小外,还应包含基类的成员变量大小;
如果基类包含虚函数,那么派生出来的类对象也应该包含一个虚函数表指针;
所有内存占用应遵循内存对其的原则;
先看下面代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#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;
}
|
运行结果如下:
[img=http://b97.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/B2jOZUWjjqr.Ak2uVl76fQRB6qooUUwRzHWcZEJ2x60!/b/Yfa82zlFcAAAYtMm1zm2cAAA][/img]
这里可以看到,普通数据成员的内存分配顺序,是按照声明变量的顺序来排序的,跟共有私有无关;
[img=http://b99.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/U1fipFp4ZxGz6KC71C.rql*tdQxD1h2z8w3NsVEyBK4!/b/YSVOCDvBbwAAYljMBjs8bgAA][/img]
当我们试图在类外访问对象的私有数据时,会提示无法访问;
有没有一种方法绕过这种限制呢?
[img=http://b100.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/NEBcJHAGOPGQ.bW2vIcJ0zM6st.2*rbL3ngLYWj2npE!/b/YYYysDsLVAAAYsTpoDuFUwAA][/img]
这里我们看到可以通过一些其他手段访问私有数据;
有人问了 如果有多个私有数据怎么访问?
综合上面的知识,把代码做了如下修改,再看结果:
[img=http://b102.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/7n4dmQalAUDq1Zztjy8KYh1dBVaKl2ES*Y3pBZiJiIE!/b/YTWm0zz.JwAAYle22Ty5JwAA][/img]
可以看到,我们通过其他手段还是能够绕过私有数据的权限进行访问的;
详解一下:
声明变量s后,调用构造函数给s的三个成员a,b,c变量赋值55,66,77;
这时s内部的结构为:
[img=http://b104.photo.store.qq.com/psb?/2fb002c1-853a-4e26-9859-d79af27c9684/0yIfQTSbYJuB8Xkc1f2UuSTMhsG4fLvWH3PrxvvcoRw!/b/YW9OAz5MJwAAYjnXBz4uJwAA][/img]
我们前面证明了,在没有其他情况的前提下(比如虚函数需要在开始位置添加一个指向虚函数表的指针);
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的大小而已;
好了就这点东西吧.