C++ 强制转换语法样式

C++ cast syntax styles

提问人:palm3D 提问时间:8/28/2008 最后编辑:Communitypalm3D 更新时间:12/23/2016 访问量:18742

问:

常规演员表、static_cast演员表和dynamic_cast相关的问题:

在 C++ 中,您更喜欢哪种强制转换语法样式?

  • C 样式强制转换语法:(int)foo
  • C++ 样式的强制转换语法:static_cast<int>(foo)
  • 构造函数语法:int(foo)

它们可能不会翻译成完全相同的指令(是吗?),但它们的效果应该是相同的(对吧?

如果您只是在内置数值类型之间进行转换,我发现 C++ 样式的强制转换语法太冗长了。作为一名前 Java 编码员,我倾向于使用 C 风格的强制转换语法,但我当地的 C++ 专家坚持使用构造函数语法。

你觉得怎么样?

C++ 编码样式 强制转换

评论

1赞 SuperStormer 1/2/2022
这回答了你的问题吗?什么时候应该使用static_cast、dynamic_cast、const_cast和reinterpret_cast?

答:

1赞 CiNN 8/28/2008 #1

C 风格的强制转换语法,不进行错误检查。 C++ 风格的强制转换语法,进行一些检查。 使用static_cast时,即使它不做检查,至少你知道在这里应该小心。

评论

1赞 underscore_d 5/13/2017
static_cast始终检查源类型和目标类型是否兼容。(如果用户将基转换为实际上没有的派生类型,则无法保护用户免受错误的影响,但这是他们的错。
16赞 hometoast 8/28/2008 #2

根据 Stroustrup 的说法:

引入了“新式演员” 给程序员一个陈述的机会 他们的意图更明确,更 编译器捕获更多错误。

所以真的,这是为了安全起见,因为它做了额外的编译时检查。

1赞 DrPizza 8/28/2008 #3

C型演员是最糟糕的方式。它更难看到,不可理解,混淆了不应该混为一谈的不同动作,并且不能做 C++ 风格转换可以做的所有事情。他们真的应该从语言中删除 C 风格的强制转换。

61赞 Konrad Rudolph 8/28/2008 #4

最佳做法是永远不要使用 C 样式强制转换,主要原因有三个:

  • 如前所述,这里不执行任何检查。程序员根本无法知道使用了各种强制转换中的哪一种,这削弱了强类型
  • 新的演员阵容故意在视觉上引人注目。由于强制转换经常暴露代码中的弱点,因此有人认为在代码中显示强制转换是一件好事。
  • 如果使用自动化工具搜索演员表,则尤其如此。可靠地找到 C 型铸件几乎是不可能的。

正如palm3D所指出的:

我发现 C++ 风格的强制转换语法太冗长了。

出于上述原因,这是故意的。

构造函数语法(正式名称:函数式强制转换)在语义上与 C 式强制转换相同,出于同样的原因,也应避免使用(声明中的变量初始化除外)。即使对于定义自定义构造函数的类型,这是否应该成立也是值得商榷的,但在 Effective C++ 中,Meyers 认为即使在这些情况下,您也应该避免使用它们。举例说明:

void f(auto_ptr<int> x);

f(static_cast<auto_ptr<int> >(new int(5))); // GOOD
f(auto_ptr<int>(new int(5));                // BAD

这里实际上会调用构造函数。static_castauto_ptr

评论

15赞 Blindy 12/5/2010
我想知道你有多少次用自动化工具在代码中搜索强制转换......
2赞 Konrad Rudolph 12/5/2010
@Blindly:它发生了。我已经这样做了。请记住,在 C++ 中,与其他一些语言(Java、C#)不同,您通常可以在没有强制转换的情况下进行编程。代码中的每个显式强制转换都是潜在的设计缺陷。识别 C++ 代码中的强制转换是重构的重要步骤。在 C# 中,在代码中搜索强制转换当然是荒谬的——它们无处不在!
3赞 augustin 9/22/2015
你的回答有两个问题:1)你提到了“两个主要原因”,但你列出了三个。:) +1
7赞 Ruslan 1/8/2016
这里真的不是胡说八道吗?写一些东西来代替或任何类似的用户类型的对象构造是相当可怕的。// GOODstatic_cast<std::string>("hello")std::string("hello")
3赞 underscore_d 9/13/2018
那么有人应该可以毫无问题地准确地引用(a)萨特和(b)其余的“几个C++权威”所说的任何类似的东西,因为对我来说,这听起来像是(i)新闻和(ii)胡说八道。
3赞 Bill the Lizard 8/28/2008 #5

我使用static_cast有两个原因。

  1. 很清楚发生了什么。我无法在不意识到正在进行演员阵容的情况下阅读它。使用 C 型石膏,您的视线可以毫不停顿地越过它。
  2. 在我的代码中搜索我正在强制转换的每个位置都很容易。
4赞 Ben Collins 8/28/2008 #6

绝对是 C++ 风格。额外的打字将有助于防止您在不应该投射时投射:-)

8赞 Jérôme 8/28/2008 #7

关于这个主题,我遵循了Scott Meyers的建议(更有效的C++,第2项:更喜欢C++风格的强制转换)。

我同意 C++ 风格的转换很冗长,但这就是我喜欢它们的地方:它们很容易被发现,并且它们使代码更易于阅读(这比编写更重要)。

它们还迫使您考虑需要什么样的演员阵容,并选择合适的演员阵容,从而降低出错的风险。它们还将帮助您在编译时而不是在运行时检测错误。

1赞 Graeme Perrow 8/28/2008 #8

我们目前到处都在使用 C 样式的强制转换。我问了另一个选角问题,我现在看到了改用static_cast的好处,如果没有其他原因,那就是“可理解的”(我喜欢这个词)。我可能会开始使用它。

我不喜欢 C++ 风格;它看起来太像函数调用了。

评论

1赞 Evan Teran 4/4/2010
看起来函数调用可能很好,它允许您拥有共享相同样式的实用程序函数,例如用于从字符串<>数值类型转换的常见函数。但这只是一个意见。lexical_cast
1赞 CAH 2/27/2012 #9

选择 C++ 风格,更糟糕的是,构成 C++ 显式类型转换的丑陋冗长代码片段将不断提醒我们都知道的事情(即显式转换是不好的——导致咒骂的产生)。 如果您想掌握跟踪运行时错误的艺术,请不要使用 C++ 风格。

3赞 QBziZ 12/23/2016 #10

构造函数语法。C++ 是 OO,构造函数存在,我使用它们。 如果你觉得有必要对这些转换ctor进行注释,你应该对每种类型进行注释,而不仅仅是内置的。也许您使用“explicit”关键字进行转换 ctor,但客户端语法完全模仿了内置类型的 ctor 语法的作用。 可以说是可以理解的,这可能是真的,但令人惊讶的是,输入更多字符使搜索变得容易。为什么要把这些看作是特别的? 如果你正在编写包含大量 int/unsigned/...往返双精度/浮点数 - 图形 - 每次都需要写一个static_cast,公式的外观变得杂乱无章,非常不可读。 无论如何,这是一场艰苦的战斗,因为很多时候你会在不知不觉中皈依。 对于向下转换指针,我确实使用了static_cast,因为当然默认情况下不存在可以执行此操作的 ctor。