C++对象模型(一)

环境: 32 windows xp vc2008
参考书籍:《深度探索C++对象模型》第三章,作者 Stanley B.Lippman,译者 侯捷。原书因为年代久远,而当今的主流编译器和当时的编译器已经有了些差别,所以现在的C++对象模型和当时有些差别。另外,书本第85页,侯老师绘的那幅图,和书中描述不一致,需要引起注意。
暂且不考虑虚函数,虚继承,直接从下面这个最简单的继承关系开始:
#include <iostream>
using namespace std;
#pragma pack(8)
 
class a
{
public:
    char _a_i;
};
 
class b : public a
{
public:
    char _b_i;
};
 
class c : public b
{
public:
    int _c_i;
};
 
int main()
{
    c obj_c;
    cout << " sizeof(obj_c) = " << sizeof(obj_c) << endl;
    cout << " obj_c's address : " << '/t' << '/t'<< '/t' << "0x" << hex << &obj_c << endl;
    cout << " obj_c._a_i's address : " << '/t' << '/t' << "0x" 
        << hex << int(&(obj_c._a_i)) << endl;
    cout << " obj_c._b_i's address : " << '/t' << '/t' << "0x" 
        << hex << int(&(obj_c._b_i)) << endl;
    cout << " obj_c._c_i's address : " << '/t' << '/t' << "0x" 
        << hex << int(&(obj_c._c_i)) << endl;
    return 0;
}
程序的输出是:
sizeof(obj_c) = 8
obj_c's address : 0x0012FF5C
obj_c._a_i's address : 0x12ff5c
obj_c._b_i's address : 0x12ff5d
obj_c._c_i's address : 0x12ff60

从输出结果来分析,可以发现基类对象被放在了低地址,派生类成员放在了高地址,C语言中的内存对齐策略在这里仍然适用,分析问题的时候,在这里我们可以暂且把基类对象看成是派生类中的成员变量(如果基类是空类,则不适用,后面会讲)。所以a类对象占一个字节,b类对象成员占一个字节,后面是两个字节的补齐字符,接着是c类的对象成员,占4个字节,总共8个字节。

如果基类为空,那么情况会发生改变,代码如下:
class a
{
public:
};
 
class b : public a
{
public:
    static int _a_i;
    int func()
    {
        return 0;
    }
    static int sta_func();
};
 
int b::sta_func()
{
    return 0;
}
 
class c : public b
{
public:
    int i;
};
 
class d
{
public:
    a obj_a;
    int a;
};
 
int main()
{
    cout << "sizeof(a) = " << sizeof (a) << endl;
    cout << "sizeof(b) = " << sizeof (b) << endl;
    cout << "sizeof(c) = " << sizeof (c) << endl;
    cout << "sizeof(d) = " << sizeof (d) << endl;
    return 0;
}
 
此时的输出结果为:
sizeof(a) = 1
sizeof(b) = 1
sizeof(c) = 4
sizeof(d) = 8
可以发现空类的大小并不为0,而是1,这样可以保证创建一个空类对象的时候,能够正确返回一个确实存在的地址。从b的大小,我们可以看出,成员函数、静态成员变量和静态成员函数,都不会占据对象空间。这里c的大小并不为5,而是4,需要注意,在某些编译器上,c的大小是5。在vc2008里,空基类的一个字节,在派生类中已经出现了成员变量的时候,将不会再存在。即使空类是多个派生类中的一个,情况也是一样。当一个类派生自两个空类,而自己也为空的时候,其大小也是为1.如果空类不是作为基类,而是用来定义一个成员变量,那么这一个字节是存在的,d的大小也验证了这点。对于c语言中的空结构,我们可以不用担心,因为设计模型的关系,C语言中是没必要而且也不允许出现空的结构体的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值