我应该使用C++的reinterpret_cast还是C风格的cast?

9

我有以下的模板函数,可以将任何标准类型的数据转储到二进制输出流中。

template<typename T> static void
dump ( const T& v, ostream& o ) {
    o.write ( reinterpret_cast<const char*>(&v), sizeof(T));
}

我可以使用C风格的(const char*)代替reinterpret_cast。使用reinterpret_cast是否有特殊原因?我看到其他一些帖子中,reinterpret_cast被批评了。但上述用法是合法的,不能用其他东西替代,对吗?


1
我想你知道这样做的后果(即生成的文件只能由使用相同选项、相同编译器和相同架构编译的程序读取)。 - curiousguy
有人可能因为我说这话而想打我,但如果你使用C风格的转换,你可以留下一个通用的根本性评论,以表明你无法错过。在C中,也必须有某种方法来查找你的const。¯|(ツ)|¯ 当然,你应该注意危险。 - Super Cat
4个回答

14

C-Style转换的问题在于它们在幕后做了很多事情。请参见此处以获取详细说明:http://anteru.net/2007/12/18/200/

在长期来看,您应该尝试始终使用C++转换,这会让生活变得更加轻松。在这种情况下,C-Style转换的主要问题在于您可以编写(char*)(&v),而使用reinterpret_cast则需要一个额外的const_cast,因此更加安全。另外,您可以使用正则表达式轻松找到reinterpret_cast,但对于C-Style转换不可能。


2
你甚至不需要一个完整的正则表达式来进行reinterpret_cast,简单的文本搜索(在大多数编辑器中使用的“查找”功能)就足够了 :) - Matthieu M.
3
是的,我最开始说不能使用正则表达式匹配 C 风格的强制类型转换,但是最后这个句子的意思却反过来了。 - Anteru
1
你想要找出所有的演员吗? - curiousguy
假设您有一个错误,其中 Foo* 损坏(即指向无效内容),则可以通过检查是否将某些内容强制转换为 Foo* 来找到该错误,这可能不是 Foo,需要查找所有强制转换为 Foo*。 - Anteru

6

没有区别。在给定的情况下,C风格转换正是一个“reinterpret”转换。

你应该优先使用C++风格的转换,因为它们对于正在进行的转换是显式的。如果必要,C风格转换将始终尝试回退到最简单粗暴的转换,而C++风格转换仅在可能的情况下编译为预期的类型:静态转换只有在值可转换或指针/引用兼容时才成功,const-cast仅适用于源和目标是彼此的cv限定版本。reinterpret-cast明确表示您希望检查底层二进制表示形式。(请注意,通常仅有效的reinterpret-cast是那些 void- 或 char-pointer,除非它们是一些更大的诡计的一部分。)


请注意,通常唯一有效的重新解释转换是指向 void-() 指针的转换。为什么要转换为 void* - curiousguy
这里不需要使用 reinterpret_cast,使用 static_cast 就可以了。(我更喜欢标准的 implicit_cast。) - curiousguy

5

C语言风格的强制类型转换非常危险。因此,C++根据典型用途将强制类型转换分为以下类型:

dynamic_cast(expression) - 允许在适当的类层次结构之间进行转换。

const_cast(expression) - 去除const属性。

static_cast(expression) - 在某种程度上类似于C语言风格,但仍然尊重类型之间的一些不兼容性并且不允许。

reinterpret_cast(expression) - 如果仍然不符合要求,则可以使用该选项。它是C语言风格的强制类型转换,但有一个名称。因此,在大型代码库中很容易找到它。

注意:大多数情况下,“reinterpret_cast”可以通过适当的设计来消除。换句话说,“reinterpret_cast”是需要的意味着设计上可能出现了问题。

更新: 这应该是最后的选择,在上面的情况下,使用是正确的。现在提到“reinterpret_cast”会给读者留下这样的印象,即作者故意选择不关心类型安全。但是使用C语言风格的强制类型转换不会产生这种印象。


但我猜测上面代码中使用的reinterpret_cast非常直观 - 并且不符合您的重新设计注释? - shekhar
正如我之前提到的,这应该是最后的选择,在上述情况下,使用是正确的。现在提到reinterpret_cast会给读者留下这样的印象:作者故意选择不关心类型安全。但使用C风格的转换不会产生这种印象。 - rakesh

1

reinterpret_cast 在替换 static_castdynamic_cast 时是不被赞同的。但在替换 C 式转换时则是被鼓励的。

新的类型转换相比于 C 式转换有很多好处。首先,你可以限制你实际需要的转换类型;其次,使用新的类型转换比使用 C 式转换更容易进行文本搜索。


2
在文本中搜索新的转换,你做过多少次? - curiousguy
1
@curiousguy:我已经做过几次了。我很少关心我从转换中得到了什么,但我经常关心我采取了一个特定的步骤,我碰巧知道其中涉及到一个转换操作。我不是在寻找转换本身,而是在寻找其他一些我知道使用了转换的东西。 - Max Lybbert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接