我很清楚使用static_cast
而非C风格的指针类型转换的优势。
如果指针类型不兼容,则:
static_cast
将在源代码中的特定行产生编译时错误- C风格转换可能会在程序执行的“随机”点导致运行时错误
但是我找不到任何关于非指针类型的类似示例。
换句话说,对于非指针类型,两种转换方法产生相同的结果。
这个理解正确吗?或者我有遗漏的地方吗?
如果是,static_cast
是否仅用于非指针类型以维护编码一致性?
我很清楚使用static_cast
而非C风格的指针类型转换的优势。
如果指针类型不兼容,则:
static_cast
将在源代码中的特定行产生编译时错误但是我找不到任何关于非指针类型的类似示例。
换句话说,对于非指针类型,两种转换方法产生相同的结果。
这个理解正确吗?或者我有遗漏的地方吗?
如果是,static_cast
是否仅用于非指针类型以维护编码一致性?
其他两个回答中尚未提到的一个优点是,static_cast
很容易被发现。在 C++ 中,括号的含义通常非常复杂,很难发现恶意(甚至不正确)的强制转换。但当我看到以 _cast
结尾的东西时,它就像是一个精神减速带:我会放慢脚步并仔细检查为什么要破坏类型系统。
static_cast
仍然似乎做了太多的事情。 它涵盖了两个完全不相关的领域:非平凡指针转换(层次向上转换和从 void *
转换)以及算术转换。 通过 static_cast
进行所有这些实际上使它们更难以发现。 - AnT stands with Russiaarithmetic_cast
作为一种单独的转换方式。但是,我希望它有一个比完整的arithmetic_cast
更紧凑的名称(那将会很笨重)。这就是C风格转换非常适合的地方。C风格转换用于算术转换,static_cast
用于指针转换。你说它们更难以发现?我不记得有任何需要故意发现算术转换的需求。指针转换-是的,但不是算术转换。算术转换是自然的。它们不应该比例如+
运算符更容易“发现”。 - AnT stands with Russia我假设避免使用指针的简单引用并不计入。
在这种情况下:C风格的转换可以是:
const_cast
static_cast
static_cast
后跟 const_cast
,reinterpret_cast
reinterpret_cast
后跟 const_cast
需要注意的是:static_cast
对于不可访问的基类的限制被解除了。
const_cast
仅适用于指针和引用。
reinterpret_cast
仅适用于指针和引用。它包括指针与整数之间的转换,但仍需涉及指针类型。
对于static_cast
的特殊例外情况,仅适用于指针和引用。
所以,是的,通过排除指针和引用,您已经排除了 C风格转换在 static_cast
上的所有支持功能。
如果是这样的话,
static_cast
是否只用于非指针类型,以保持编码一致性?
让我们来举一个类比:我不会用链锯来打开一袋薯片。虽然我可以这样做,但链锯很危险,因此使用它会引入不必要的风险。使用链锯很容易出错,如果我使用不当,就没有安全机制可以防止事故发生。
仅用于非指针类型以保持编码一致性吗?
不仅如此,还有助于维护正确性和未来兼容性。
它有助于维护正确性,因为 static_cast
无法执行某些C样式转换。如果涉及的类型有误,这将有所帮助,例如在处理指针时却认为它是整数(在多层模板和typedefs下,这并不难想象)。因此,如果你打算进行 static_cast
,写一个并获得编译时错误,你会立即被告知所涉及的类型与你的想法不符。而使用C样式转换的“不限制任何内容”的态度,则会让你没有时间发现这个错误。
它还有助于未来的兼容性。如果转换中涉及的类型在开发后更改, static_cast
将报告错误,而C样式转换则只会默默地更改其行为(可能不是预期的行为)。
static_cast
可以帮助您强制执行这个理想的约束条件,即源类型不是指针。int *ip = new int(); long j = static_cast<long>(*ip);
是一个愚蠢的例子,但像这样编写可以捕捉到将 ip
打成 *ip
的错误,而 long(*ip)
无法捕捉到该错误,因为 long(ip)
是一个有效的 C 风格转换。 - Steve Jessop
static_cast
而不是常规转换。 - barak manos