为什么在这里使用 static_cast 而不是 reinterpret_cast 很重要?

2023-11-22

回复 Raymond Chen 博文,

有提问者指出

Raymond,我相信 C++ 示例是不正确的,因为这个位置 派生类中的基类子对象的属性未指定 根据 ISO C++ 2003 标准(10-3,第 168 页),并且您假设 基类子对象始终位于开头。 C example 在 C++ 中也很好,所以我会坚持使用它。

雷蒙德回复了

[代码没有做出这个假设。这就是为什么重要的是 使用 static_cast 而不是 reinterpret_cast。尝试一下:添加虚拟 方法重叠(因此 vtable 位于前面)并观察 编译器确实如此。 -雷蒙德]

看了他的评论我就猜到了。在示例中使用 static_cast 没问题,但reinterpret_cast 则不行。因为reinterpret_cast不是转换vtable。我的理解正确吗?
不过,如果我在那里使用 C 风格的强制转换(而不是reinterpret_cast),它也会出错吗?

我重新阅读了 More effective C++ 的强制转换解释来理解这一点。但对此没有任何答复。


在示例中使用 static_cast 没问题,但reinterpret_cast 则不行。因为reinterpret_cast不是转换vtable。

No, the problem is that the reinterpret_cast is completely oblivious about the inheritance. It will simply return the same address unchanged1. But static_cast knows that you're performing a downcast: i.e. casting from a base class to a derived class. Since it knows both types involved it adjusts the address accordingly, i.e., does the right thing.

Let's pretend我们的实施提出了假设OVERLAPPEDEX具有如下虚函数的类:

+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
       ^
       |
      ptr

我们得到的指针指向OVERLAPPED子对象。reinterpret_cast不会改变这一点。它只会改变类型。显然,访问OVERLAPPEDEX通过这个地址调用类很容易造成严重破坏,因为它的子对象的位置现在都错了!

       what we believe we have when we access OVERLAPPEDEX through the pointer
       +------+------------+------------------+-------------+
       | vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------+-----+------+-----------+------+------+------+
| vptr | OVERLAPPED | AssociatedClient | ClientState | <- what we actually have
+------+------------+------------------+-------------+
       ^
       |
      ptr

static_cast knows来转换一个OVERLAPPED* to OVERLAPPEDEX*它必须调整地址,并做正确的事情:

 +------+------------+------------------+-------------+
 | vptr | OVERLAPPED | AssociatedClient | ClientState |
 +------+------------+------------------+-------------+
 ^
 |
ptr after static_cast

不过,如果我在那里使用 C 风格的强制转换(而不是reinterpret_cast),它也会出错吗?

C 风格强制转换被定义为以下第一个成功的转换:

  1. const_cast
  2. static_cast
  3. static_cast, then const_cast
  4. reinterpret_cast
  5. reinterpret_cast, then const_cast

如您所见,一个static_cast之前尝试过reinterpret_cast,所以在这种情况下,C 风格的强制转换也会做正确的事情。


更多信息


1Not guaranteed. There are very little guarantees about what happens on a reinterpret_cast. All implementations I know of will simply give out the same address unchanged.

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

为什么在这里使用 static_cast 而不是 reinterpret_cast 很重要? 的相关文章

  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur

随机推荐

  • PhantomJS - 上传文件而不提交表单

    是否可以使用 PhantomJS 将文件上传到某个页面而无需手动提交表单 我认为使用内容类型 multipart form data 是可能的 上的例子https github com ariya phantomjs blob master
  • 访问 dplyr 中的分组数据

    从 dplyr 应用 group by 函数并使用 运算符后 如何访问分组数据 例如 如果我想要每个分组数据的第一行 那么我可以使用 plyr 包来执行此操作 ddply iris Species function df df 1 outp
  • Flask 会话如何工作?

    我很好奇 Flask 会话是如何工作的 特别是它如何在服务器重新启动之间存储信息 如果我错了 请引用我的话 我知道你必须设置一个独特的app secret key因此人们无法以任何方式解密会话并修改 cookie 因为会话的 cookie
  • 将数组中的空值替换为零值

    我有一个数组 我需要删除空值并将其替换为零 我已经取得了这么多成就 当我检查数组长度为 8 但它只显示 2 个元素时 用零替换它的最佳方法是什么 var a a 3 5 a 5 15 console log a length 6 conso
  • 获取相关实体 ASP.NET WebApi OData v4 导致“未找到与请求 URI 匹配的 HTTP 资源”

    我跟着Mike Wasson 的这个 ASP NET 教程 并设法很好地设置了相关实体 但是当我将此逻辑应用于我的项目时 更复杂的实体关系 因为实体关系更多 这是唯一的区别 在 OData 调用中不会成功 我收到带有此有效负载的 404 e
  • 找不到模块 FBSDKCoreKit Cocoapods

    我正在尝试使用 CocoaPods 使用 use frameworks 将 facebook 集成到我的应用程序中 标签 并根据 Facebook 的此处说明 还包括吊舱螺栓 当我尝试使用时import FBSDKCoreKit在我的 ap
  • 代理与自然/业务密钥[关闭]

    Closed 这个问题是基于意见的 目前不接受答案 又来了 老争论依然出现 我们是否最好将业务键作为主键 或者我们宁愿使用对业务键字段具有唯一约束的代理 ID 即 SQL Server 标识 请提供例子或证据来支持你的理论 使用代理键的几个
  • 按连接值对 R 数据帧进行分组

    我没有找到 R 中这个常见分组问题的解决方案 这是我的原始数据集 ID State 1 A 2 A 3 B 4 B 5 B 6 A 7 A 8 A 9 C 10 C 这应该是我分组的结果数据集 State min ID max ID A 1
  • SVN 术语 - 签出、工作副本、属性、存储库

    当我尝试学习如何使用时svn externals 我很难理解这些术语的差异 它们有何不同 工作副本 and checkout 有时构建是有用的工作副本这是由许多不同的结账 source property 在 Subversion 中 您可以
  • 哪个性能更好: test != null 或 null != test [重复]

    这个问题在这里已经有答案了 考虑以下两行代码 if test null and if null test 从性能角度来看 上述两种说法有什么区别吗 我见过很多人使用后者 当被问及时 他们说这是最佳实践 但没有充分的理由 没有不同 第二个原因
  • 导入web3到next js会报错

    我正在使用 next js 和 Material ui 构建一个用于学习的演示 dapp 我已经安装了元掩码 到目前为止我只能设置一个 连接到钱包 按钮 我陷入了必须导入 Web3 构造函数的困境 我的代码如下所示 我的包 json 的屏幕
  • 如何删除文件最后一行的最后一个字符? [复制]

    这个问题在这里已经有答案了 我在一个文件中有这组行 info info info info 我想要这样的文件 没有最后一个 info info info info 我怎样才能在 bash 中做到这一点 任何想法 您可以使用sed sed s
  • 确保控制器在 Unity 中具有无参数公共构造函数

    我在控制器上遇到了这个问题 尝试创建类型为 的控制器时发生错误 WebMvc Controllers HomeController 确保控制器具有无参数公共构造函数 找到了ApiController的解决方案 但是没有找到关于普通Contr
  • $this->render 和 $this->redirect Symfony2 之间的区别

    this gt render 和 this gt redirect 之间有什么区别 有没有一种方法可以像我使用 this gt redirect 那样使用 this gt render 传递参数 return this gt render
  • jQuery:如何确定单击了哪个
  • 标签?
  • 我正在创建一个包含 5 行文本的表单 每个文本都允许用户选择是否希望文本居中 左对齐或右对齐 我有一个未编号的列表 其中列表元素为 x5 li img src images justify left png alt left span Ju
  • AWS - 通过 EBS 实现跨可用区冗余的任何方法

    我正在寻找 EBS 的冗余解决方案 理想情况下 我们会在每个可用区都有一个 EBS 卷 类似于主从配置 当主 EBS 卷发生故障时 所有读 写操作都将定向到辅助卷 该卷用于存储应用程序的用户数据 而不是操作系统或应用程序文件或类似的内容 将
  • 如何使用 Get-ChildItem -exclude 排除多个文件夹?

    我需要为我们的 Pro Engineer CAD 系统生成一个配置文件 我需要我们服务器上特定驱动器的文件夹的递归列表 但是 我需要排除其中包含 ARCHIVE 的任何文件夹 包括各种不同的情况 我写了以下内容 除了不排除文件夹外 它可以工
  • Android Alarm AlarmManager 提供的四种 Alarm 有什么区别以及何时使用什么?

    我想知道之间的区别RTC RTC WAKEUP ELAPSED REALTIME ELAPSED REALTIME WAKEUP 我想编写一个闹钟应用程序 我将在其中设置闹钟并关闭我的应用程序 并期望在设置的时间发出闹钟 会有多个警报 现在
  • 如何在 ASP.Net 应用程序中设置默认时区

    您好 我创建了 ASP NET Web 应用程序 没有考虑时区 我直接使用 DateTime Now 函数 实际上 这会以服务器配置的时区格式返回日期时间 现在我无法更改整个应用程序 那么有什么方法可以将应用程序的时区设置为独立于托管该应用
  • 为什么在这里使用 static_cast 而不是 reinterpret_cast 很重要?

    回复 Raymond Chen 博文 有提问者指出 Raymond 我相信 C 示例是不正确的 因为这个位置 派生类中的基类子对象的属性未指定 根据 ISO C 2003 标准 10 3 第 168 页 并且您假设 基类子对象始终位于开头