C++11 中的 POD 和继承。 struct的地址==第一个成员的地址吗?

2023-11-22

(我编辑了这个问题以避免分心。在任何其他问题有意义之前,需要先解决一个核心问题。向任何现在看来答案似乎不那么相关的人道歉。)

让我们设置一个具体的例子:

struct Base {
    int i;
};

没有虚方法,也没有继承,通常是一个非常愚蠢和简单的对象。因此它是普通旧数据 (POD)它回归到可预测的布局。尤其:

Base b;
&b == reinterpret_cast<B*>&(b.i);

这是根据维基百科(其本身声称引用了 C++03 标准):

指向 POD 结构对象的指针(使用重新解释强制转换进行适当转换)指向其初始成员,反之亦然,这意味着 POD 结构的开头没有填充。 [8]

现在让我们考虑继承:

struct Derived : public Base {
};

同样,没有虚拟方法,没有虚拟继承,也没有多重继承。因此这也是 POD。

问题:这个事实(Derived 是 C++11 中的 POD)是否允许我们这样说:

Derived d;
&d == reinterpret_cast<D*>&(d.i); // true on g++-4.6

If这是正确的,那么以下将是明确定义的:

Base *b = reinterpret_cast<Base*>(malloc(sizeof(Derived)));
free(b); // It will be freeing the same address, so this is OK

我不是问关于new and delete这里 - 更容易考虑malloc and free。我只是好奇在这样的简单情况下有关派生对象布局的规定,以及基类的初始非静态成员位于可预测的位置。

派生对象是否应该等同于:

struct Derived { // no inheritance
    Base b; // it just contains it instead
};

事先没有填充?


你不关心 POD 性,你关心的是标准布局。这是来自标准第 9 节的定义[class]:

标准布局类是这样的类:

  • 没有非标准布局类(或此类类型的数组)类型的非静态数据成员或引用,
  • 没有虚函数 (10.3) 和虚基类 (10.1),
  • 对所有非静态数据成员具有相同的访问控制(第 11 条),
  • 没有非标准布局基类,
  • 要么在最远的派生类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,要么没有具有非静态数据成员的基类,并且
  • 没有与第一个非静态数据成员相同类型的基类。

然后你想要的财产就得到了保证(第 9.2 节[class.mem]):

指向标准布局结构对象的指针,使用适当转换reinterpret_cast, 指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。

这实际上比旧的要求更好,因为能够reinterpret_cast不会因添加重要的构造函数和/或析构函数而丢失。


现在让我们转向你的第二个问题。答案不是你所希望的。

Base *b = new Derived;
delete b;

是未定义的行为,除非Base有一个虚拟析构函数。参见第 5.3.5 节([expr.delete])

在第一种选择(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。


您之前的片段使用malloc and free大部分是正确的。这会起作用:

Base *b = new (malloc(sizeof(Derived))) Derived;
free(b);

因为指针的值b与placement new 返回的地址相同,而new 又与从placement new 返回的地址相同malloc.

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

C++11 中的 POD 和继承。 struct的地址==第一个成员的地址吗? 的相关文章

随机推荐

  • 如何解决 AZFD0005 Azure Function App 错误

    目前 Node Azure Function App 存在抛出错误的问题AZFD0005 节点应用程序在本地运行良好 Azure 的具体错误是 Microsoft Azure WebJobs Script ExternalStartupEx
  • 如何减少 numpy 数组的维数?

    我从一个mxnxp array A In 16 A Out 16 array 2 10000000e 01 3 70060693e 01 2 00000000e 01 2 15659121e 01 1 50000000e 01 1 3500
  • 如何从命令行将 EOF 发送到 Python sys.stdin? CTRL-D 不起作用

    我正在从 unix 上的命令行写入我的 Python 进程 我想发送 EOF 或以某种方式刷新标准输入缓冲区 以便 Python 可以读取我的输入 如果我按下 CTRL C 就会出现键盘错误 如果我按下 CTRL D 程序就会停止 如何刷新
  • 将 AngularJS 嵌套表单设置为已提交

    我有一个嵌套的 AngularJS 表单 如下所示
  • 如何在 Android 上将 UTC 日期转换为本地 GMT 时间

    我有这个日期字符串 2016 04 26T09 14 10 477Z这是在 UTC 时区 我想将其转换为用户本地时区 因此如果是 GMT 02 00 我想要一个值为2016 04 26T11 14 10 477Z 注意 9 更改为 11 到
  • 使用适用于 Android 的 Smack Api 发送和接收消息

    自过去四天以来 我一直在尝试使用自己的 XMPP 和 Smack OpenFire 发送和接收聊天消息 根据Smack的 readme txt 我设置了连接并登录了用户 连接和登录的代码是这样的 public static String T
  • Magento - 从优惠券代码获取规则

    我必须检索与优惠券代码关联的规则 以便在报价中显示该规则的折扣百分比 最简单的方法是直接根据报价金额进行计算 但我想直接检索规则 然后从中获取折扣百分比 这就是我尝试过的 rule Mage getModel salesrule coupo
  • 编写新 DialogPreference 类的简洁方法?

    我正在通过扩展在 Android 中编写一些自定义首选项对话框DialogPreference班级 但是 我有点担心所需的样板代码量 因为似乎有很多行为需要测试 例如 这个数字首选项对话框的示例相当典型 http svn jimblackl
  • Python 中一张图中的多个图

    我是 python 新手 正在尝试使用 matplotlib 在同一个图中绘制多条线 我的 Y 轴的值存储在字典中 我在以下代码中在 X 轴中制作相应的值 我的代码是这样的 for i in range len ID AxisY PlotP
  • 在webview中加载flv视频的问题

    我想要load网络视图中的 flv 视频 我已经得到了帮助这个链接 但问题是我无法在模拟器中查看视频 这是我的代码 package com FlvTester import java lang reflect InvocationTarge
  • 来自闪亮应用程序的写入权限

    这是对此的后续问题 write csv 许可闪亮服务器 R 我正在使用一个闪亮的应用程序来搜索和保存一些数据 我在获取文件夹权限时遇到问题 读完这篇文章后 https groups google com forum topic shiny
  • Hadoop MapReduce 读取文本文件

    我正在尝试编写一个 MapReduce 程序 它可以读取输入文件并将输出写入另一个文本文件 我计划为此使用 BufferedReader 类 但我真的不知道如何在 MapReduce 程序中使用它 我怎样才能为其编写代码片段 附 我对 Ha
  • Meteor.js:查找所有文档并以相反的自然顺序返回

    我正在尝试返回集合中的所有文档 以将其与模板中的 each 一起使用 我的代码如下所示 return Answers find sort natural 1 但文档按自然顺序返回 而不是反向 有谁知道为什么 我从 MongoDB 文档中获取
  • WinMerge:如何在比较中忽略特定单词?

    当我在 Windows 平台上使用 WinMerge 比较 2 个文件时 您知道如何忽略特定单词吗 我的意思是我想对 WinMerge 说 不要关心那串单词 房子 花园等 所以当比较这两行时 the house is at london t
  • 由于来自 localhost 的 CORS 问题,请求失败

    我在 SO 和不同的博客上看到了几十个问题 并用 答案 谈论这个问题 但都无济于事 我的本地计算机 Ubuntu 16 04 上有一个 React js 应用程序 在本地 我尝试通过运行来测试它npm start它会打开浏览器http 本地
  • 列出所有当前打开的文件句柄? [复制]

    这个问题在这里已经有答案了 可能的重复 检查Python中打开了哪些文件 Hello 是否可以获得所有当前打开的文件句柄的列表 我认为它们存储在环境中的某个位置 我对这个函数感兴趣 因为我想安全地处理出现致命错误时打开的任何文件 即关闭文件
  • 使用 Python 使用 IAM 角色连接到 Redshift

    我正在使用 sqlalchemy 和 psycopg2 将 python 连接到 redshift engine create engine postgresql user password hostname port database n
  • Slick,如何将查询映射到继承表模型?

    Slick 如何将查询映射到继承表模型 IE 我有表A B C A 是 父 表 B 和 C 是 子 表 我想知道的是我应该如何使用 slick 对此进行建模 以便 A 将是抽象的 B C 具体类型 并且查询 A 中的行将导致 B 或 C 对
  • 为什么 for_each 通过 move 返回函数

    我正在阅读文档std for each here http en cppreference com w cpp algorithm for each并看到返回值是std move f 为什么标准强制在返回值中移动输入参数 既然输入参数是按值
  • C++11 中的 POD 和继承。 struct的地址==第一个成员的地址吗?

    我编辑了这个问题以避免分心 在任何其他问题有意义之前 需要先解决一个核心问题 向任何现在看来答案似乎不那么相关的人道歉 让我们设置一个具体的例子 struct Base int i 没有虚方法 也没有继承 通常是一个非常愚蠢和简单的对象 因