static_cast 有用之处

总的来说,应该尽量避免类型转换(dynamic_cast 除外)。使用类型转换常常会引起类型错误或者数值截断。甚至于看起来“无辜”的类型转换也有可能变成很严重的问题,如果在开发或者维护期间,其中一个相关的类型改变了的话。例如,下面这个是什么意思:

x = (T)y;

我们不得而知。这取决于类型 T 以及 x 和 y 的类型。T 可能是类的名字、typedef 或者模板参数。可能 x 和 y 都是标量变量,而 (T) 代表值的转换。也可能 x 是 y 的派生类的对象,而 (T) 是一个向下转换(downcast)。还可能 x 和 y 是不相关类型的指针。由于 C 风格的类型转换 (T) 可用于表述很多逻辑上不同的操作,所以编译器很难捕捉误用。同样的道理,程序员不可能精确地知道类型转换到底做了什么。有些菜鸟程序员认为这是一个有利条件,但假若他们错误地判断了形势,将会导致许多细微的错误。

“新风格的类型转换”因此应运而生,它给予了程序员更清晰地表达他们的真实意图的机会,也使得编译器能捕捉到更多错误。例如:

static_cast 所允许的转换都比需要使用 reinterpret_cast 才能进行的转换更安全,更不易出错。大体上,可以直接使用 static_cast 转换后的值,而无需将其再转换成原来的类型。而由 reinterpret_cast 得到的值却总是应该被转换成原来的类型后才使用,这样才能确保可移植性。

引入新风格类型转换的第二个原因是,C 风格的类型转换在程序中难以被发现。例如,在普通的编辑器或者文字处理软件里,你不能方便地查找类型转换。C 风格类型转换的这一隐秘性实在是糟透了,因为类型转换潜在着极其高的破坏性。丑陋的操作应该使用丑陋的语法形式。这个事实也是选择新风格类型转换语法的部分依据。更深一层的原因是,让新风格的类型转换语法和模板语法一致,这样程序员就能编写自己的类型转换,尤其是带运行时检查的类型转换。

或许,因为 static_cast 很难看,而且也相对难拼,所以你更可能会充分考虑后才决定是否使用它?这很好,因为现代 C++ 里,类型转换真的是最容易避免的。