Data Member 的布局

考察以下代码:

class Point3d
{
public:
    //...    
private:
    float _x;
    static List<Point3d*> *freeList;
    float _y;
    static const int chunkSize = 250;
    float _z;
};

其中, nonstatic data members 在 class object 中的排列顺序和其被声明的顺序是一致的, 但是任何介入的 static data members 都不会被放进布局之中。static data members 都存放在程序的 data segment 中, 和个别的 class objects 无关。
C++ Standard 要求, 在同一个 access section (即 private, public, protected 等) 中,members 的排列只需符合较晚出现的 members 在 class object 中有着较高的地址这一条件即可。 也就是说, 各个 members 并不一定要连续排列(意味着中间可被其他区段分隔)。那么有什么会可能被插在中间呢? 第一种是为了对齐所填补的 bytes, 第二种就是编译器可能会合成一些内部使用的 data mambers, 以支持整个对象模型, vptr 就是这样的东西, 当前的所有编译器都把它安插在每一个内含 virtual function 的 class object 之内。而 vptr 又会被放在什么位置呢?传统上它被放在所有声明的 members 的最后, 但是有的编译器也把 class object 的最前端。 这是因为 C++ standard 秉承先前所说的“对于布局放任的态度”, 所以允许编译器吧内部产生的 members 自由放在任何位置上, 甚至放在那些被程序员声明的 members 之前。
当然, 既然是放任的态度, C++ standard 也允许编译器将多个 access sections 之中的 data members 自由排列, 不必在乎它们出现在 class 声明中的次序, 意味着形如:

class Point3d
{
public:
    //...
private:
    float _x;
    static List<Point3d*> *freeList;
private:
    float _y;
    static const int chunkSize = 250;
private:
    float _z;
};

实际上与前一段代的大小和组成是一样的, 我的理解就是, 只要你是搞革命的, 我们不管你是从哪来的。 而实际在编译器中, 编译器可以随意把 y 或 z 或什么其他东西放为第一个, 但似乎目前的编译器没人这么做。
编译器实际的处理都是把一个以上的 access section 连锁在一起, 依照声明的次序连成一个连续区块。 Access section 的多寡不会引起编译器的额外负担, 不管是在几个 sections 中 声明多个 members, 还是在一个一个 section 中声明全部的 members, 得到的 object 的大小都是一样的。
考察以下代码:

//接受两个 data members, 判断谁先出现在 class object 之中。 
//如果两个 members 都是不同的 access sections 中的第一个被声明的
//此函数就可以判断哪一个 section 先出现
template< class class_type,
      class data_type1,
      class data_type2 >
char*
access_order(
    data_type1 class_type::*mem1,
    data_type2 class_type::*mem2 )
{
    assert(mem1 != mem2);
    return 
        mem1 < mem2
            ?"member 1 occurs first"
            :"member 2 occurs first";
}

上述函数可以这样被调用:
access_order( &Point3d::_z, &Point3d::_y );
PS: 但是, 我在 vs2013 上运行这段代码没有成功, 显示的错误是 error C2296: “<”: 非法,左操作数包含“int Point3d::* ”类型
这就让人不淡定了, 希望如果有人看到这篇博客可以指点一二, 我先在这谢谢了!

posted @ 2014-11-18 21:21  wu_overflow  阅读(186)  评论(0编辑  收藏  举报