为什么工会静态成员不存储为工会?

Dmy*_*yka 1 c++ union static-members

在C ++中,union可以包含静态成员,这些静态成员与类一样属于一个类,因此对于所有对象都是公共的。

union U
{
   long l;
   int i;
   static long sl;
   static int si;
};

int U::si;
long U::sl;
Run Code Online (Sandbox Code Playgroud)

逻辑上期望所有联合静态成员存储在与非静态成员存储类似的相同地址上。但事实并非如此。一个简单的示例显示静态成员存储在不同的地址下,并且可以包含独立的值。

int main()
{
   U u;
   u.si = 10;
   u.sl = 50;

   std::cout << "Non-static members adresses: " << &u.i << " " << &u.l << std::endl;
   std::cout << "Static members adresses: " << &u.si << " " << &u.sl << std::endl;
   std::cout << "Static members values: " << u.si << " " << u.sl << std::endl;
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Non-static members adresses: 006FF8EC 006FF8EC
Static members adresses: 00AEB144 00AEB140
Static members values: 10 50
Run Code Online (Sandbox Code Playgroud)

我不明白为什么独立值存储留在联合中。我认为这具有误导性,没有任何意义。不过,在我看来,这是有原因的。union静态成员的目的是什么?

Nic*_*las 7

您可以从两个角度看待这个问题。

C ++观点:

工会首先是一个阶级。它的目的不同于班级,但它是由班级告知的。

联合是一类,其任何一种类型的其子对象中只有一个是活动的。为此,它更改了联合的成员子对象的工作方式。这也是为什么联合不能具有基类子对象的部分原因。

静态数据成员不是成员子对象,因此它们在联合中的布置应与它们在非联合类中的布置没有区别。

此外,C ++中类型的静态成员实际上只是函数和对象名称的作用域机制。它们仍然有效地是全局的,但是它们可以是私有的也可以是隐藏的,并且必须为它们加上类型名作为前缀,以便您使用它们。

联合的静态数据成员的行为与类的静态数据成员的行为实际上没有任何意义。

C ++必须与C兼容:

联合存在于C中,因此C ++也必须拥有它们。但是联合很难在C ++对象模型中定义,使用起来很麻烦,还有很多其他事情。因此,您可以将并集视为C ++需要但不愿处理的事情。那么您如何处理它们?

在处理C工会的工作方式时,使工会像C一样工作。C中没有静态成员这样的东西,因此没有C代码期望将静态联合成员组合在一起。因此...不要将它们结合在一起。如果用户确实需要一个静态成员,该成员是某种类型的并集,则他们可以轻松地创建一个并创建该类型的单个静态成员。

因此,通过使静态成员有所不同,用户不会失去任何表达能力。