为什么工会静态成员不存储为工会?
Why union static members not stored as a union?
In C++union
可以包含静态成员,这些静态成员与类一样,属于一个类,因此对所有对象都是通用的。
union U
{
long l;
int i;
static long sl;
static int si;
};
int U::si;
long U::sl;
期望所有联合静态成员存储在同一地址类似于非静态成员存储是合乎逻辑的。但事实并非如此。一个简单的示例显示静态成员存储在不同的地址下,并且可以包含独立的值。
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;
}
输出:
Non-static members adresses: 006FF8EC 006FF8EC
Static members adresses: 00AEB144 00AEB140
Static members values: 10 50
我不明白为什么独立的价值存储留在工会中。我认为这是误导,毫无意义。尽管如此,在我看来,这是有原因的。union
静态成员的目的是什么?
你可以从两个角度来看待这个问题。
C++视角:
工会首先是一个阶级。它有一个不同于类的目的,但它是由类是什么来告知的。
联合是一个类,其子对象在任一类型中只有一个处于活动状态。为此,它改变了工会的成员子对象的工作方式。这也是联合不能有基类子对象的部分原因。
静态数据成员不是成员子对象,因此它们在联合中的处置应该与它们在非联合类中的处置没有什么不同。
此外,C++ 中类型的静态成员实际上只是函数和对象名称的作用域机制。它们仍然是有效的全局的,但它们可以是私有的和隐藏的,并且它们必须以它们的类型名称为前缀才能使用它们。
联合的静态数据成员的行为与类的静态数据成员没有任何不同,这实际上没有任何意义。
C++必须与 C 兼容的视角:
联合存在于 C 中,所以C++也必须拥有它们。但是联合很难在C++对象模型中定义,使用起来很痛苦,还有很多其他事情。因此,你可以将工会视为C++需要拥有但宁愿不处理的事情。那你怎么处理他们呢?
在处理 C 工会的工作方式时,你让工会像 C 一样工作。在 C 中没有静态成员这样的东西,所以没有 C 代码期望静态联合成员被组合在一起。因此。。。不要将它们组合在一起。如果用户确实需要一个静态成员,该成员是一组类型的联合,则他们可以轻松地创建联合并创建该类型的单个静态成员。
因此,用户不会因为使静态成员与众不同而失去任何表达能力。
联合是一次最多保存一个数据成员的类 [basic.compound]p1.6 [class]p7 [class.union],并且对于其静态数据成员没有特殊规则,其余类类型(即class
和struct
)。
因此,静态数据成员的行为与所有类中的行为相同。
如果要拥有一个由多种类型联合的静态数据成员,则可以执行以下操作:
union U {
long l;
int i;
union {
long l;
int i;
} static s;
};
decltype(U::s) U::s;
// They are the same indeed
static_assert(&U().s.l == &U().s.l);
您需要通过s
引用元素,例如 不过,s.l
而不是sl
。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 如何在C++中使用非静态成员函数作为回调函数
- (C++)为什么静态成员可以在初始化之前使用
- 类的全局对象和静态成员
- 在作为静态成员包含在另一个类中的类的构造函数中使用 cout
- 模板化类中静态成员的延迟初始化
- 使用静态成员声明类时遇到问题
- C++:是否可以使用非静态成员变量模板?
- 静态成员函数使用相同的名称时出现模板类型名称错误
- 如何在复杂继承中访问静态成员变量
- 如何创建存储指向成员函数的指针的类 (C++)
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 如何在友元函数中使用静态成员而不添加前缀 [类名]::
- C++构造函数和静态成员
- 为什么传递非静态成员函数会导致编译错误?
- 非静态成员失败的线程调用函数
- 静态成员变量不会由 gettext 转换
- 将存储类声明为主机类中的静态成员
- 为什么工会静态成员不存储为工会?
- OpenGL/ c++将所有纹理资源作为静态成员存储在一个单独的类中