只是想问为什么以下是正确的:
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)单位。那两个变量之间是否有碎片漏洞,从而让这个算子返回假值?
答案 0 :(得分:6)
保证x
,y
和z
在内存中总是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;