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];
};