C++对象的地址

这里是一些资料:

 

详细的参看《C++对象模型》

C++98标准规定的类存储空间如下:

1.出于执行效率的考虑,所有的成员函数都在编译时期转换为普通函数,所以不占运行期类内存空间;

2.非静态成员,根据数据类型分配相应空间,顺序不确定,目前大部分编译器都按声明顺序分配;

  静态成员,在全局数据区,不占类存储空间。

3.存在虚函数的,由于虚函数是运行期绑定,必须分配运行期内存空间,考虑提高存储空间,采用统一的虚函数表

  存储该类的所有虚函数,而所有类对象会添加一个指向该表的指针vptr;

4.存在继承关系,派生类会增加基类的存储空间(不是全部可见);

5.如果是虚继承,则会在派生类增加虚基类的索引指针,保证只有一份拷贝;

6.空间对齐,处于硬件处理效率的考虑(最大化数据通路传输能力)#pragma pack(n),一般32位处理器,n=4;

  但是空类不作对齐处理,会增加一个char成员,即为1Byte,目的是为了区分不同空类对象;

来自:http://blog.csdn.net/freshgamer/archive/2010/05/09/5573063.aspx

 

下面给出一些测试的代码:

#include "stdafx.h"

#include <iostream>

using std::cout;

using std::endl;

 

1、无继承

 

     输出结果:

 

the value of bird size is::8

the value of &bird is::0x13FF5C

the value of &(bird.m_type) is::0x13FF5C

the value of &(bird.m_weight) is::0x13FF60

 

2、单继承无虚函数

 

     输出结果:

the value of bird size is::16

the value of &bird is::0x13FF54

the value of &(bird.m_Life0No) is::0x13FF54

the value of &(bird.m_Life0Zone) is::0x13FF58

the value of &(bird.m_type) is::0x13FF5C

the value of &(bird.m_weight) is::0x13FF60

 

3、单继承有虚函数

 

     输出结果:

the value of bird size is::20

the value of &bird is::0x13FF50

the value of &(bird.m_Life0No) is::0x13FF54

the value of &(bird.m_Life0Zone) is::0x13FF58

the value of &(bird.m_type) is::0x13FF5C

the value of &(bird.m_weight) is::0x13FF60

 

4、单虚继承无虚函数

 

     输出结果:

the value of bird size is::20

the value of &bird is::0x13FF50

the value of &(bird.m_Life0No) is::0x13FF5C

the value of &(bird.m_Life0Zone) is::0x13FF60

the value of &(bird.m_type) is::0x13FF54

the value of &(bird.m_weight) is::0x13FF58

 

5、单虚继承有虚函数

 

     输出结果:

the value of bird size is::24

the value of &bird is::0x13FF4C

the value of &(bird.m_Life0No) is::0x13FF5C

the value of &(bird.m_Life0Zone) is::0x13FF60

the value of &(bird.m_type) is::0x13FF50

the value of &(bird.m_weight) is::0x13FF54

 

6、分析

 

无继承

单继承

无虚函数

单继承

有虚函数

单虚继承

无虚函数

单虚继承

有虚函数

bird size

8

16

20

20

24

&bird

0x13FF5C

0x13FF54

0x13FF50

0x13FF50

0x13FF4C

&(bird.m_Life0No)

 

0x13FF54

0x13FF54

0x13FF5C

0x13FF5C

&(bird.m_Life0Zone)

 

0x13FF58

0x13FF58

0x13FF60

0x13FF60

&(bird.m_type)

0x13FF5C

0x13FF5C

0x13FF5C

0x13FF54

0x13FF50

&(bird.m_weight)

0x13FF60

0x13FF60

0x13FF60

0x13FF58

0x13FF54

分析结果

对象地址=

m_type的地址

对象地址=

m_Life0No的地址

对象地址=

指向虚函数表的指针的地址

对象地址=

0x13FF50应该是虚基类的索引指针

对象地址=

0x13FF4C(我分不清楚

0x13FF4C

0x13FF58,哪个是虚基类的索引指针,哪个是指向虚函数表的指针的地址)

分结论

1、对象的地址是第一个声明的非静态成员变量的地址

2、非静态成员变量声明越靠后地址值越大

1、对象地址是父类中第一个声明的非静态成员变量的地址

2父类中的任一非静态成员变量的地址小于子类中任一非静态成员变量地址

3、父类(或者子类)非静态成员变量声明越靠后地址值越大。

1、对象地址是指向虚函数表的指针的地址

2父类中的任一非静态成员变量的地址小于子类中任一非静态成员变量地址

3、父类(或者子类)非静态成员变量声明越靠后地址值越大。

1、对象地址是虚基类的索引指针

2父类中的任一非静态成员变量的地址大于子类中任一非静态成员变量地址

3、父类(或者子类)非静态成员变量声明越靠后地址值越大。

1、对象地址是最小的地址

2父类中的任一非静态成员变量的地址大于子类中任一非静态成员变量地址

3、父类(或者子类)非静态成员变量声明越靠后地址值越大。

总结论

1、对象的地址是该对象拥有的所有地址中的最小地址;

2、每个类中的非静态成员变量的声明顺序将会决定其地址值的大小,声明越靠后,地址值越大;

3、继承和虚继承会影响父类和子类地址的分配顺序;

4、以上的前提条件是在VS2008环境、无空类、无静态成员变量的情况下测试出来的;

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值