设为首页 加入收藏

TOP

4.11.3 显式转换(2)
2013-10-07 16:28:43 来源: 作者: 【 】 浏览:112
Tags:4.11.3 转换

4.11.3  显式转换(2)

我们必须牢记pc所指的真实对象是一个int而非字符,如果把pc当成普通的字符指针使用就可能在运行时发生错误。例如:

  1. string str(pc); 

可能导致异常的运行时行为。

使用reinterpret_cast是非常危险的,用pc初始化str的例子很好地证明了这一点。其中的关键问题是类型改变了,但编译器没有给出任何警告或者错误的提示信息。当我们用一个int的地址初始化pc时,由于显式地声称这种转换合法,所以编译器不会发出任何警告或错误信息。接下来再使用pc时就会认定它的值是char*类型,编译器没法知道它实际存放的是指向int的指针。最终的结果就是,在上面的例子中虽然用pc初始化str没什么实际意义,甚至还可能引发更糟糕的后果,但仅从语法上而言这种操作无可指摘。查找这类问题的原因非常困难,如果将ip强制转换成pc的语句和用pc初始化string对象的语句分属不同文件就更是如此。

reinterpret_cast本质上依赖于机器。要想安全地使用reinterpret_cast必须对涉及的类型和编译器实现转换的过程都非常了解。

建议:避免强制类型转换

强制类型转换干扰了正常的类型检查(参见2.2.2节,第46页),因此我们强烈建议程序员避免使用强制类型转换。这个建议对于reinterpret_cast尤其适用,因为此类类型转换总是充满了风险。在有重载函数的上下文中使用const_cast无可厚非,关于这一点将在6.4节(第232页)中详细介绍;但是在其他情况下使用const_cast也就意味着程序存在某种设计缺陷。其他强制类型转换,比如static_cast和dynamic_cast,都不应该频繁使用。每次书写了一条强制类型转换语句,都应该反复斟酌能否以其他方式实现相同的目标。就算实在无法避免,也应该尽量限制类型转换值的作用域,并且记录对相关类型的所有假定,这样可以减少错误发生的机会。

旧式的强制类型转换

在早期版本的C++(www.cppentry.com)语言中,显式地进行强制类型转换包含两种形式:
 

  1. type (expr);        // 函数形式的强制类型转换  
  2. (type) expr;        // C语言风格的强制类型转换 

根据所涉及的类型不同,旧式的强制类型转换分别具有与const_cast、static_cast或reinterpret_cast相似的行为。当我们在某处执行旧式的强制类型转换时,如果换成const_cast和static_cast也合法,则其行为与对应的命名转换一致。如果替换后不合法,则旧式强制类型转换执行与reinterpret_cast类似的功能:
 

  1. char *pc = (char*) ip; // ip是指向整数的指针 

的效果与使用reinterpret_cast一样。

与命名的强制类型转换相比,旧式的强制类型转换从表现形式上来说不那么清晰明了,容易被看漏,所以一旦转换过程出现问题,追踪起来也更加困难。

4.11.3节练习

练习4.36:假设i是int类型,d是double类型,书写表达式i*=d使其执行整数类型的乘法而非浮点类型的乘法。

练习4.37:用命名的强制类型转换改写下列旧式的转换语句。

int i; double d; const string *ps; char *pc; void *pv;

(a) pv = (void*)ps;  (b) i = int(*pc);

(c) pv = &d;    (d) pc = (char*) pv;

练习4.38:说明下面这条表达式的含义。

  1. double slope = static_cast<double>(j/i); 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇优化C++代码(4):消除冗余代码 下一篇3.4 迭代器介绍

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: