结构体的内存布局

看《Thinking in C++》的时候有下面一段代码:
 

#include <iostream>
 
 using namespace std;
 
 struct A{
     int i[100];
 };
 
 struct B{
     void f();
 };
 
 void B::f() {}
 
 int main()
 {
     cout << "sizeof struct A = " << sizeof(A);
     cout << "sizeof struct B = " << sizeof(B);
     return 0;
 }

作者说sizeof(A)很容易理解,但是sizeof(B)不是0有些不正常。他解释到这是因为C++不允许两个object的内存地址是一样的,如果sizeof(B) = 0,那么两个连续的struct B的变量的定义,就会导致这两个变量的地址一样。
而我在想的却是另外一个问题:struct B的大小不应该是4吗?它应该要存函数f()的地址啊。但结果却是1。这个1只是为了让变量的地址有所区别吧。google了一下之后,发现我的想法只是我的一厢情愿。
1. 函数f()的代码是在代码段的某个位置;
2. 因为f()对于多个struct B变量是公共的,它的地址对所有的struct B变量是一样的,它根本就不需要存放在每个struct B变量里。f()的地址应该是在编译的时候就已经确定了的。
这样的话,所有的函数都是不用占空间的(虚函数除外,那是另外一回事了);仔细一想,这种做法确实比在每个struct变量里存放函数地址的做法要好,而且,更重要的一点,它实现了与C的兼容性。C的结构体是不能带有成员函数的。C++的实现方式使得下面的两个结构体是完全一样的:
 
// C struct
 struct C{
     int value;
 };
 
 // C++ struct
 struct CPP{
     int value;
     void fn();
 };
 

如果用sizeof()查看的话,struct C和struct CPP占用的内存是一样的。都是4。甚至可以在struct C和struct CPP之间进行任意转换,因为它们的内存布局是完全一样的。

#include <iostream>

using namespace std;

// C struct
struct C{
    int value;
};
 
// C++ struct
struct CPP{
    int value;
    void fn();
};

int main()
{
    struct C a;
    a.value = 100;

    struct CPP *b = (struct CPP*)&a;
    cout << "value = " << b->value;

    b->value = 200;
    cout << "value = " << a.value;

    return 0;
}


输出的结果是:
value = 100
value = 200

posted @ 2011-01-16 19:41  冰封的水  阅读(598)  评论(0编辑  收藏  举报