C++ 使用union在简单结构中使用成员变量别名
我想继承一个简单的点C++ 使用union在简单结构中使用成员变量别名,c++,inheritance,unions,C++,Inheritance,Unions,我想继承一个简单的点struct: struct PointXYZ { double x, y, z; }; class extendedPoint : public PointXYZ { public: double getXYZ(int i); void setXYZ(int i, double value); private: int moreproperties; }; get set函数是索引函数,因为我希望能够循环获取和设置xyz值。我想通过修改我
struct
:
struct PointXYZ
{
double x, y, z;
};
class extendedPoint : public PointXYZ
{
public:
double getXYZ(int i);
void setXYZ(int i, double value);
private:
int moreproperties;
};
get set函数是索引函数,因为我希望能够循环获取和设置xyz值。我想通过修改我的基类,将索引xyz和独立的x,y,z的概念联系起来,如回答中所述:
但与第一篇关于以下内容是否有效的文章直接矛盾:
double dostuff()
{
PointXYZ p;
p.x = 123.88;
return p.xyz[0];
}
<> P> >代码> PoxTyxz < /C>使用<代码>联合<代码>有效C++和编译器之间是否一致?< P>标准:
在联合中,在任何时候最多可以有一个非静态数据成员处于活动状态,即at的值
大多数非静态数据成员可以随时存储在联合中。[注:一项特别担保
是为了简化联合体的使用:如果一个标准布局联合体包含多个标准布局联合体
共享公共初始序列(9.2)的结构,如果是此标准布局联合类型的对象
包含一个标准布局结构,允许检查任何
标准布局结构构件;见9.2.-尾注]
在我看来,特别保证表明
struct PointXYZ {
union {
struct {
double xyz[3];
};
struct {
double x, y, z;
};
};
};
在读取上次写入的成员()时,应该可以正常工作
但是,请注意,根据规范,您的
struct PointXYZ {
union {
struct {
double xyz[3];
};
double x, y, z;
};
};
读取上次写入的成员()时的未定义行为。设置xyz[0]
、xyz[1]
和xyz[2]
时,所有x
、y
和z
的值都与链接示例中的xyz[0]
相同。我希望大多数编译器都会这样做,但标准并不能保证这一点
struct PointXYZ {
union {
double xyz[3];
struct {
double x, y, z;
};
};
};
根据编译器/平台的不同,您可能会遇到数据对齐问题(可能,但不太可能)
x
,y
,z
不能与xyz[0]
,xyz[1]
,xyz[2]
对应地驻留在内存中
C++保证xyz
数组的元素是连续排列的,但它只保证结构元素的地址大于所有先前声明的元素的地址(当然,许多编译器提供了用于控制打包和对齐的#pragma)
关于类型双关语问题(从不同的工会成员那里阅读的实践,而不是最近写信给的人)。。。
你可以说这不是类型双关(类型匹配,所以没有双关,它只是混叠),<强>但是仍然,从语言标准的角度来看,写入和读取的成员是不同的,这在C++中是不确定的。
总之,一般来说,你会得到预期的结果
使用GCC,它甚至可以保证工作(即使使用-fstrict别名):
作为一个旁注,考虑匿名联盟是允许的,但是C++禁止匿名结构(很多编译器允许它们)。 下面的解决方案怎么样
class PointXYZ
{
public:
double getXYZ(unsigned i) { return xyz[i]; }
void setXYZ(unsigned i, double value) { xyz[i] = value; }
double &x() { return xyz[0]; }
double &y() { return xyz[1]; }
double &z() { return xyz[2]; }
private:
double xyz[3];
};
我真的不记得了,但是包装/校准怎么样?数组的规则是否与结构字段相同?不应该在这里明确设置打包/对齐吗?@quetzalcatl据我所知,两者都应该占用连续内存。不过,我必须承认,我并不是100%同意。这两个匿名结构是否共享一个共同的初始序列?这是一个有趣的例外,你在std中发现了。你对这些示例使用了哪种编译器?多亏了你的示例,我才注意到我最初的示例代码显然是错误的。我已经切换了结构中包装的成员以避免明显的错误。这似乎是一个可行的解决方案,但我希望保持PointXYZ接口尽可能简单(击键次数更少)。啊,是的。。。我没有做这个选项,因为MSVC2010不支持初始值设定项列表,所以我想要私有成员
x,y,z
而不是xyz[3]
,这使得getXYZ()
和setXYZ()
实现有点奇怪。我能想到的最简单的实现是double-getXYZ(inti){return(&x)[I];}
,但这似乎引入了其他潜在问题。。。
class PointXYZ
{
public:
double getXYZ(unsigned i) { return xyz[i]; }
void setXYZ(unsigned i, double value) { xyz[i] = value; }
double &x() { return xyz[0]; }
double &y() { return xyz[1]; }
double &z() { return xyz[2]; }
private:
double xyz[3];
};