gpt4 book ai didi

c++ - 无论存储类型如何,是否允许访问 union 成员的公共(public)基类?

转载 作者:太空狗 更新时间:2023-10-29 20:21:00 24 4
gpt4 key购买 nike

考虑一个 union 体,其成员共享一个公共(public)基类:

struct Base {
int common;
};

struct DerivedA : Base {};
struct DerivedB : Base {};

union Union {
DerivedA a;
DerivedB b;
};

无论 union 在运行时“包含”什么(即最后存储的值是什么),只要它包含一些东西,那东西就是 Base 的子类。那么有没有什么方法可以合法地使用这个想法来访问 Base 字段,而无需知道 union 中存储的对象的实际类型?

也许是这样的:

Base* p = reinterpret_cast<Base*>(&u);

...可能不会。也许是这样的:

Base* p2 = static_cast<Base *>(&u.a);

如果 u.b 是最后存储的值是否合法?

我知道有关于适用于 union 的“公共(public)初始序列”的特殊规则,但不清楚基类是否有类似的规则。

显然它不适用于多重继承,所以这可能表明它根本不起作用。

最佳答案

您输入的示例实际上是有效的,但它不允许进行很多有用的更改。

union 非事件成员的任何部分唯一有效的左值到右值转换是访问该成员与事件成员 ([class.mem]/23) 的公共(public)初始序列的一部分。

但公共(public)初始序列仅针对两个标准布局结构 ([class.mem]/20) 定义,并且对于什么符合标准布局结构 ([class]/7) 有相当多的规则.总结:

  • 类不能是多态的。

  • 同一类的基类不能超过一个。

  • 类不能有引用类型的非静态成员。

  • 该类的所有非静态成员都具有相同的访问控制。

  • 包括继承成员在内的所有非静态成员首先在同一个类中声明。

  • 所有基类和非静态成员(包括继承成员)递归地遵守上述所有规则。

  • 有规则规定标准布局结构的第一个非静态成员与结构具有相同的地址,并且标准布局 union 的所有非静态成员具有相同的地址联盟。但是,如果这些规则的任何组合意味着相同类型的两个对象必须具有相同的地址,则包含的结构/union 不是标准布局。

(最后一个规则的例子:

struct A {};           // Standard-layout
struct B { A a; }; // Standard-layout (and &b==&b.a)
union U { A a; B b; }; // Not standard-layout: &u.a==&u.b.a ??
struct C { U u; }; // Not standard-layout: U is not.

)

您的 DerivedADerivedB 都是标准布局,因此允许它们具有共同的初始序列。事实上,该公共(public)序列是每个的单个 int 成员,因此它们实际上是完全布局兼容的(因此可能是包含这两个结构的其他一些结构对的公共(public)初始序列的一部分).

不过,这里比较棘手的事情之一是关于属于同一类的所有成员的规则。如果向 DerivedA 和/或 DerivedB 添加任何非静态成员,即使向两者添加相同类型的成员,更改的结构也是/根本不再是标准布局,因此没有共同的初始序列。这限制了您希望在此模式中使用继承的大多数现实原因。

关于c++ - 无论存储类型如何,是否允许访问 union 成员的公共(public)基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46637954/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com