为什么使用 static_cast(x) 而不是 (T)x?

2023-11-23

我听说static_cast函数应该优先于 C 风格或简单函数风格的转换。这是真的?为什么?


主要原因是经典的 C 类型转换不区分我们所说的static_cast<>(), reinterpret_cast<>(), const_cast<>(), and dynamic_cast<>()。这四件事是完全不同的。

A static_cast<>()通常是安全的。语言中有一个有效的转换,或者有一个适当的构造函数使之成为可能。唯一有点冒险的时候是当你向下转换为继承类时;您必须通过语言外部的方式(如对象中的标志)确保该对象实际上是您声称的后代。 Adynamic_cast<>()只要检查结果(指针)或考虑可能的异常(引用),就是安全的。

A reinterpret_cast<>() (or a const_cast<>())另一方面总是危险的。你告诉编译器:“相信我:我知道这看起来不像foo(这看起来好像它是不可变的),但它是”。

第一个问题是,如果不查看大量分散的代码并了解所有规则,几乎不可能判断 C 风格类型转换中会出现哪一个。

让我们假设这些:

class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere

现在,这两个以相同的方式编译:

CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
                                     // Safe; as long as we checked
                                     // but harder to read

然而,让我们看看这段几乎相同的代码:

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error.
                                                  // Same as reinterpret_cast<>
                                                  // and it's wrong!!!

正如您所看到的,如果不了解所有涉及的类,就没有简单的方法来区分这两种情况。

第二个问题是 C 风格的强制转换太难定位。在复杂的表达式中,很难看到 C 风格的强制转换。如果没有成熟的 C++ 编译器前端,几乎不可能编写需要定位 C 风格转换的自动化工具(例如搜索工具)。另一方面,搜索“static_cast

pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
      // No compiler error.
      // but the presence of a reinterpret_cast<> is 
      // like a Siren with Red Flashing Lights in your code.
      // The mere typing of it should cause you to feel VERY uncomfortable.

这意味着,不仅 C 风格的强制转换更加危险,而且找到它们以确保它们正确也更加困难。

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

为什么使用 static_cast(x) 而不是 (T)x? 的相关文章

  • 转换 const void*

    我有一个函数返回一个const void 我想用它的信息作为char 我可以将它投射为 C 风格的罚款 char variable但是当我尝试使用reinterpret cast like reinterpret cast
  • MVC3中设置下拉列表中的所选项目

    我必须为视图中的下拉列表设置所选项目 但它不起作用 View div class editor label Html LabelFor model gt model Gender div div class editor field Htm
  • 当事件button.click发生时,如何获取按钮名称/标签?

    我以编程方式制作按钮并将它们添加到堆栈面板中 以便每次用户导航到页面时按钮都会发生变化 我正在尝试做这样的事情 当我单击创建的按钮时 它将获取按钮的标签并转到正确的页面 但是 我无法使用 RoutedEventHandler 访问按钮元素
  • 无法注册时间触发的后台任务

    对于 Windows 8 应用程序 在 C Xaml 中 我尝试注册后台任务 很难说 但我想我的后台任务已正确注册 但是当我单击调试位置工具栏上的后台任务名称时 我的应用程序停止工作 没有任何消息 我查看了事件查看器上的日志 得到 具有入口
  • RestSharp获取序列化输出

    我正在寻找一种方法来访问 AddBody 调用的序列化结果 我正在使用内置的 RestSharp 序列化器 例子 class Foo public string FooField void SendRecord var f new Foo
  • 语音识别编程问题入门

    所以 你们可能都看过 钢铁侠 其中托尼与一个名为贾维斯的人工智能系统进行交互 演示剪辑here http www youtube com watch v Go8zsh1Ev6Y 抱歉 这是广告 我非常熟悉 C C 和 Visual Basi
  • 在 C# 中,如何根据在 gridview 行中单击的按钮引用特定产品记录

    我有一个显示产品网格视图的页面 该表内有一列 其中有一个名为 详细信息 的超链接 我想这样做 以便如果用户单击该特定产品的详细信息单元格 将打开一个新页面 提供有关该产品的更多信息 我不确定如何确定哪个Product记录链接的详细信息以及我
  • 如何使用 ASP.NET Core 获取其他用户的声明

    我仍在学习 ASP NET Core 的身份 我正在进行基于声明的令牌授权 大多数示例都是关于 当前 登录用户的 就我而言 我的 RPC 服务正在接收身份数据库中某个用户的用户名和密码 我需要 验证是否存在具有此类凭据的用户 获取该用户的所
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • 不可变类与结构

    以下是类与 C 中的结构的唯一区别 如果我错了 请纠正我 类变量是引用 而结构变量是值 因此在赋值和参数传递中复制结构的整个值 类变量是存储在堆栈上的指针 指向堆上的内存 而结构变量作为值存储在堆上 假设我有一个不可变的结构 该结构的字段一
  • 在 C 中使用枚举而不是 #defines 作为编译时常量是否合理?

    在 C 工作了一段时间后 我将回到 C 开发领域 我已经意识到 在不必要的时候应该避免使用宏 以便让编译器在编译时为您做更多的工作 因此 对于常量值 在 C 中我将使用静态 const 变量或 C 11 枚举类来实现良好的作用域 在 C 中
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 没有“对 *this”功能的右值引用的解决方法

    我有一个围绕可移动对象的代理容器类 并希望代理能够隐式生成对底层对象的右值引用 但仅当代理本身被移动时 我相信我将能够按照提案 n2439 实施此行为 将移动语义扩展到 this http www open std org jtc1 sc2
  • 是否允许全局静态标识符以单个 _ 开头?

    换句话说 可能static 文件范围 全局变量恰好以一个下划线开头 而不会产生与 C 实现发生名称冲突的可能性 https www gnu org software libc manual html node Reserved Names
  • MySqlConnectionStringBuilder - 使用证书连接

    我正在尝试连接到 Google Cloud Sql 这是一个 MySql 解决方案 我能够使用 MySql Workbench 进行连接 我如何使用 C 连接MySqlConnectionStringBuilder 我找不到提供这三个证书的

随机推荐

  • 某些函数式编程结构是否会降低可调试性?

    我听说以下功能会降低可调试性 因为它们是匿名的 调试器无法很好地跟踪它 匿名类 内部类 闭包块 Lambda 函数 这是真的 关于您提到的特定功能 已经有一些很好的答案 一般来说 我想说一些 FP 功能以及以更多 FP 风格进行编程的方面至
  • 您是否应该实现 IDisposable.Dispose() 以使其永远不会抛出异常?

    对于 C 中的等效机制 析构函数 建议是 它通常不应该抛出任何异常 这主要是因为这样做可能会终止进程 这很少是一个好的策略 在 NET 中的等效场景中 抛出第一个异常 由于第一个异常而执行了finally块 finally 块调用 Disp
  • 是否可以在常规对象(而非 DOM 对象)上分派事件? [复制]

    这个问题在这里已经有答案了 我刚刚发现 FileReader 调度事件就像它是 DOM 元素一样 是吗 我想知道是否可以创建一个类似于 FileReader 的对象 它没有 HTML XML 结构的表示 但可以调度事件 FileReader
  • async.each 和 async.eachSeries 之间的区别

    Is 异步每个作为异步数组迭代工作 Is async eachSeries作为同步数组迭代工作 它实际上等待响应 我问这些是因为两者都有回调 但 async each 的工作方式类似于异步数组迭代 This is traditional w
  • 序列化可选的 where 子句参数?

    这是一件让我真正烦恼的事情 我必须为几乎相同的查询编写两个不同的函数 假设我有一个返回的 APIposts与特定的相关联typeId and cityId 要得到ALL相关帖子typeId 1 OR 2 OR 3 and cityId 1我
  • VB.NET静态代码分析

    有谁知道 vb net 的良好代码静态代码分析吗 我见过很多关于 c 的内容 我认为 VS 2008 内置了一些 但我们目前只使用 vs 2005 FxCop就是这么做的 具体针对 VB NET 的是项目分析器
  • 如何从 html 按钮调用 Firefox 扩展中的函数

    如何使用网页中的 html 按钮调用在我的扩展中声明的 Javascript 函数 我有一个 html 页面 里面有一个按钮 当用户单击该按钮时 它将调用我已经在自己的 Firefox 扩展中声明的函数 由于您控制网页 因此执行您想要的操作
  • 按共享列值合并关联数组的数组[重复]

    这个问题在这里已经有答案了 我想根据公共列值合并两个数组 这是我的 2 个数组 array1 total process per category gt 6 category id gt 1 total process per catego
  • 如何使用 NSDistributedNotifications 在进程之间共享核心数据存储?

    背景 我已经发布了一个关于基础知识的问题在进程之间共享核心数据存储 我正在尝试实施给出的建议 但遇到了问题 My Goal 我有两个进程 Helper App 和 UI 它们都共享一个数据存储 当助手应用程序将新数据保存到商店时 我希望 U
  • 如何在 R 中重命名具有特定模式的文件?

    有一些 fcs文件在一个数据 000X目录中的格式 其中 X 1 2 3 我想重命名每个n文件格式如下 exp fcs where exp是来自向量的文本 如果要重命名的文件是 fcs file 换句话说 我想将文件重命名为exp txt
  • 将 PCAP 跟踪转换为 NetFlow 格式

    我想将一些 PCAP 跟踪转换为 Netflow 格式 以便使用 netflow 工具进行进一步分析 有什么办法可以做到这一点吗 具体来说 我想使用 flow export 工具从 netflow 跟踪中提取一些感兴趣的字段 如下所示 fl
  • php 中用于缩小/压缩 javascript 的简单正则表达式搜索和替换?

    你能在 php 中发布正则表达式搜索和替换来缩小 压缩 javascript 吗 例如 这是一个简单的 CSS header Content type text css ob start compress function compress
  • Java 正则表达式 - 重叠匹配

    在下面的代码中 public static void main String args List
  • Java正则表达式精确匹配8位数字

    我有一个简单的正则表达式 应该查找 8 位数字 String number scanner findInLine d 8 但事实证明 它也匹配9位或更多位的数字 如何修复此正则表达式以精确匹配 8 位数字 例如 12345678应该匹配 而
  • 安装镶木地板工具

    我正在尝试在 FreeBSD 机器上安装 parquet 工具 我克隆了这个仓库 git clone https github com apache parquet mr 然后我做了cd parquet mr parquet tools 然
  • 在 OCUnit 中使用核心数据类时出现 Apple Mach-O 链接器错误

    好的 这是我的测试类中的代码 NSManagedObjectContext managedObjectContextWithConcurrencyType NSManagedObjectContextConcurrencyType conc
  • 什么是 CSRF 代币?它的重要性是什么?它是如何运作的?

    我正在编写一个应用程序 Django 确实如此 我只想了解 CSRF 令牌 实际上是什么以及它如何保护数据 如果不使用CSRF token 发布的数据会不安全吗 简单来说 跨站请求伪造 CSRF 假设您当前已登录网上银行 www myban
  • 在 MySql 中将 VARCHAR 转换为 DECIMAL 值

    我已将包含字符串值 例如吃 和浮动值 例如 0 87 的 CSV 文件导入到我的 phpMyAdmin 数据库中的表中 在处理完所有字符串值并仅保留具有十进制值的行后 我需要将这些值从 VARCHAR 转换为 DECIMAL FLOAT 以
  • 定点的反平方根

    我正在寻找定点 16 16 数字的最佳反平方根算法 下面的代码是我到目前为止所拥有的 但基本上它取平方根并除以原始数字 我想得到不除法的倒数平方根 如果它发生任何改变 代码将为armv5te编译 uint32 t INVSQRT uint3
  • 为什么使用 static_cast(x) 而不是 (T)x?

    我听说static cast函数应该优先于 C 风格或简单函数风格的转换 这是真的 为什么 主要原因是经典的 C 类型转换不区分我们所说的static cast lt gt reinterpret cast lt gt const cast