类变量 - 对齐

时间:2013-01-16 14:47:34

标签: c++ operators

  

可能重复:
  Classes store data members in sequential memory?

只是想问为什么以下是正确的:

template<class T>
class Vec3 {
public:
  // values
  T x,y,z;

  // returns i-th komponent (i=0,1,2) (RHS array operator)
  const T operator[] (unsigned int i) const {
    return *(&x+i);
  }
}

或换句话说:为什么始终保证x,y和z总是在内存中的sizeof(T)单位。那两个变量之间是否有碎片漏洞,从而让这个算子返回假值?

2 个答案:

答案 0 :(得分:6)

保证xyz在内存中总是sizeof(T)单位。可以在两者之间添加填充字节 它被遗漏作为实施细节 唯一保证的是,在类/结构的开头和POD结构/类的第一个成员之间不会有填充。

无法保证代码中operator[]的实施始终有效。

<强>参考:
C ++ 11:9.2类成员[class.mem]

  

14)分配具有相同访问控制(第11条)的(非联合)类的非静态数据成员   后来的成员在类对象中有更高的地址。非静态数据的分配顺序   具有不同访问控制的成员未指定(11)。 实施对齐要求可能会   导致两个相邻成员不能立即分配; 所以可能需要   管理虚函数(10.3)和虚基类(10.1)的空间。

答案 1 :(得分:0)

为了避免碎片漏洞,您可以通过以下方式控制对齐:

#ifdef compiling_with_msvc
#pragma pack(1)
#endif
template<class T>
class Vec3 {
public:
    // values
    T x,y,z;

    // returns i-th komponent (i=0,1,2) (RHS array operator)
    const T operator[] (unsigned int i) const {
        return *(&x+i);
    }
#ifdef compiling_with_gcc
}__attribute__((packed));
#else
};
#endif

如果您可以使用C++11 compiler,则可以standard way控制对齐。

但如果您不关心班级的记忆表现形式,请考虑使用union

template <typename T>
union Vec3
{
    T x, y, z;
    struct
    {
        T value[3];
    } vector;
};

使用联盟,您不必关心对齐,以便使用[]访问每个组件:

Vec3<unsigned int> v3;

v3.vector.value[0] = 1;
v3.vector.value[1] = 2;
v3.vector.value[2] = 3;