无论存储的类型如何,是否允许访问联合成员的公共基类?

2024-03-13

考虑一个联合,其成员共享一个公共基类:

struct Base {
    int common;
};

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

union Union {
    DerivedA a;
    DerivedB b;
};

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

也许是这样的:

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

... 可能不会。也许这个:

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

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

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

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


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

联合非活动成员的任何部分上唯一有效的左值到右值转换是使用活动成员 ([class.mem]/23) 访问该成员的公共初始序列的一部分。

但公共初始序列仅为两个标准布局结构体 ([class.mem]/20) 定义,并且对于标准布局结构体 ([class]/7) 的资格有相当多的规则。总结:

  • 该类可能不是多态的。

  • 一个类不能有多个相同类型的基类。

  • 该类可能没有引用类型的非静态成员。

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

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

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

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

(最后一条规则的示例:

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.

)

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无论存储的类型如何,是否允许访问联合成员的公共基类? 的相关文章

  • 将集合绑定到自定义控件属性

    我没有运气尝试将数据集合绑定到我的自定义控件的属性 我已经实现了该控件的字符串属性的机制 在此处提供了一些帮助 并期望集合类型同样简单 但是我无法让它再次工作 这是我的自定义控件视图
  • 在实体框架拦截器中向 DbScanExpression 添加内部联接

    我正在尝试使用实体框架 CommandTree 拦截器通过 DbContext 向每个查询添加过滤器 为了简单起见 我有两个表 一个称为 User 有两列 UserId 和 EmailAddress 另一个称为 TenantUser 有两列
  • 如何保证对象只有一个线程

    我有以下代码 class Service public void start creates thread which creates window and goes to message loop void stop sends WM C
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • VS 程序在调试模式下崩溃,但在发布模式下不崩溃?

    我正在 VS 2012 中运行以下程序来尝试 Thrust 函数查找 include cuda runtime h include device launch parameters h include
  • 读取 C# 中的默认应用程序设置

    我的自定义网格控件有许多应用程序设置 在用户范围内 其中大部分是颜色设置 我有一个表单 用户可以在其中自定义这些颜色 并且我想添加一个用于恢复默认颜色设置的按钮 如何读取默认设置 例如 我有一个名为的用户设置CellBackgroundCo
  • 指向特征矩阵的指针数组

    我在代码中使用 Eigen 的 MatrixXd 矩阵 在某个时刻我需要一个 3D 矩阵 由于 Eigen 没有三维矩阵类型 因为它仅针对线性代数进行了优化 因此我创建了一个 MatrixXd 类型的指针数组 Eigen MatrixXd
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • 时间:2019-03-17 标签:c#ThreadSafeDeepCopy

    我一直在阅读很多其他问题以及大量谷歌搜索 但我一直无法找到明确的解决方案 根据我读过的一些最佳实践 类的静态方法应该创建线程安全的 并且实例成员应该将线程安全留给消费者 我想为该类实现深度复制方法 该类本身还有其他引用类型成员 有没有什么方
  • 类的成员复制

    在学习 复制成员 概念时 书中给出了如下说法 此外 如果非静态成员是引用 const 或没有复制赋值的用户定义类型 则无法生成默认赋值 我不太明白这个声明到底想传达什么 或者说这个说法指的是哪一种场景 谢谢 该语句与编译器自动为您编写的类
  • std::forward_as_tuple 将参数传递给 2 个构造函数

    我想传递多个参数以便在函数内构造两个对象 以同样的方式std pair
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • 检查 RoutedEvent 是否有任何处理程序

    我有一个自定义 Button 类 当单击它时 打开特定窗口 它总是执行相同的操作 我添加了一个可以在按钮的 XAML 中分配的 Click 事件 就像常规按钮一样 当它被单击时 我想执行 Click 事件处理程序 如果已分配 否则我想执行默
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 如何分析组合的 python 和 c 代码

    我有一个由多个 python 脚本组成的应用程序 其中一些脚本正在调用 C 代码 该应用程序现在的运行速度比以前慢得多 因此我想对其进行分析以查看问题所在 是否有工具 软件包或只是一种分析此类应用程序的方法 有一个工具可以将 python
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • cout 和字符串连接

    我刚刚复习了我的 C 我尝试这样做 include
  • 使用taskkill停止Windows服务

    我需要帮助来使用 C 终止 Windows 服务 现在要终止该服务 请使用以下选项 从命令 sc queryex ServiceName 发现后PID服务的 taskkill pid 1234 exemple f 为了便于阅读 但如果您明白
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • 使我的 COM 程序集调用异步

    我刚刚 赢得 了在当前工作中维护用 C 编码的遗留库的特权 这个dll 公开使用 Uniface 构建的大型遗留系统的方法 除了调用 COM 对象之外别无选择 充当此遗留系统与另一个系统的 API 之间的链接 在某些情况下 使用 WinFo

随机推荐