5

可能重复:
类将数据成员存储在顺序内存中?

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

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) 单位。在这两个变量之间不能有碎片漏洞,从而让这个运算符返回一个假值吗?

4

2 回答 2

6

不能保证x,y和总是在内存中分开zsizeof(T)中间可以添加填充字节。
它作为实现细节被忽略了。
唯一可以保证的是,在类/结构的开头与其 POD 结构/类的第一个成员之间不会有填充。

不能保证operator[]您的代码中的实现将始终有效。

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

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

于 2013-01-16T14:48:43.920 回答
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 编译器,您可以以标准方式控制对齐。

但是,如果您不关心类的内存表示,请考虑使用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;
于 2013-01-16T15:03:03.710 回答