当前位置: 首页 > news >正文

C++ 中的强制类型转换

  显示转换也成为强制类型转换(cast),包括以下列名字命名的强制类型转换操作符:static_cast、dynamic_cast、const_cast、reinterpret_cast。

 

1. const_cast  const_cast<TYPE> (object); 

   The const_cast keyword can be used to remove the const or volatile property from an object. The target data type must be the same as the source type, except (of course) that the target type doesn't have to have the same const qualifier. The type TYPE must be a pointer or reference type.

 

 2. static_cast  static_cast<TYPE> (object);

  The static_cast keyword can be used for any normal conversion between types. This includes any casts between numeric types, casts of pointers and references up the hierarchy, conversions with unary constructor, conversions with conversion operator. For conversions between numeric types no runtime checks if data fits the new type is performed. Conversion with unary constructor would be performed even if it is declared as explicitIt can also cast pointers or references down and across the hierarchy as long as such conversion is available and unambiguous. No runtime checks are performed

 

3. dynamic_cast  dynamic_cast<TYPE&> (object);  dynamic_cast<TYPE*> (object)

  The dynamic_cast keyword casts a datum from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast. 

  If you attempt to cast to a pointer type, and that type is not an actual type of the argument object, then the result of the cast will be NULL.

  If you attempt to cast to a reference type, and that type is not an actual type of the argument object, then the cast will throw a std::bad_cast exception.

   用于将基类类型对象的引用或者指针转换为同一继承层次中其他类型的引用或者指针。使用指针时,指针必须是有效的,为0或者指向一个对象。与其他强制类型转换不同,它涉及运行时类型检查。如果绑定到引用或者指针的对象不是目标类型的对象,则dynamic_cast转换失败。如果转换到指针类型的dynamic_cast失败,则dynamic_cast的结果是0值;如果转换到引用类型的dynamic_cast失败,则抛出一个bad_cast类型的异常。

  一般而言,引用或者指针所绑定的对象的类型在编译时是未知的,基类的指针可以赋值为指向派生类对象,同样,基类的引用也可以用派生类对象初始化,因此dynamic_cast操作符执行的验证必须在运行时进行。

ExpandedBlockStart.gif dynamic_cast
if  (Derived  * derivedPtr  =  dynamic_cast < Derived *> (basePtr))
{
        
//      use the Derived object to which derivedPtr points
else
        
//  BasePtr points at a Base object
        
//  use the Base object to which basePtr points
    }

void  f( const  Base  & b)
{
    
try  {
            
const  Derived  & =  dynamic_cast < const  Derived &> (b);
            
//  use the Derived object to which b referred
        }  catch  (bad_cast) {
            
//  handle the fact that the cast failed
        }
}

 

4. reinterpret_cast  reinterpret_cast<TYPE> (object);

  The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Different operators for different uses

The four casting operators in C++ can be used in different cases, where each is most appropriate:

static_cast is the most useful cast. It can be used to perform any implicit cast. When an implicit conversion loses some information, some compilers will produce warnings, and static_cast will eliminate these warnings. Making implicit conversion through static_cast is also useful to resolve ambiguity or to clarify the conversion presence. It also can be used to call a unary constructor, declared as explicit. It also can be used to cast up and down a class hierarchy, like dynamic_cast, except that no runtime checking is performed.

const_cast is used to apply or remove const or volatile qualifier from a variable.

dynamic_cast is used on polymorphic pointers or references to move up or down a class hierarchy. Note that dynamic_cast performs runtime-checks: if the object's type is not the one expected, it will return NULL during a pointer-cast and throw a std::bad_cast exception during a reference-cast.

reinterpret_cast is used to perform conversions between unrelated types, like conversion between unrelated pointers and references or conversion between an integer and a pointer.

Old-style cast may correspond to static_cast, reinterpret_cast or const_cast, or even a combination of them. This means that none of these casting operators is as powerful as old-style cast.

 

小记:

  1、static_cast不进行错误检查,可以进行的转换有:数字类型、继承层次中的指针或引用、声明为explicit的单形参构造函数。只要用来进行替换编译器进行的    隐式转换。

  2、dynamic_cast进行错误检查,可以进行的转换:继承层次中的指针或者引用。 

  3、const_cast用来添加或者去掉一个变量的const或者volatile属性,这个变量必须是指针或引用类型。 

  4、旧时转型(C风格转型)有两种形式:(T) expression 或 T (expression)。两种形式并无差别,纯粹只是小伙考的位置不同。如:

 

class  Widget {
public :
  
explicit  Widget( int  size);
}; 
void  doSomeWork ( const  Widget &  w);
doSomeWork( Widget(
15 ) );             // 旧风格
doSomeWork( static_cast < Widget > ( 15 ) );    // 新风格 

 

 

   5、const_cast 通常被用来将对象的常量性移除。它也是唯一有此能力的C++ style 转型操作符。static_cast 用来强迫隐式转换,例如将 non_const 对象转换为cosnt 对象(就像条款3所为),但它无法将const转换为非const。

  6、static_cast 可以将一个derived class对象转换为base class对象。但static_cast返回一个derived class对象的base class部分的一个副本:

class  Window {
pubilc:
    
virtual   void  onResize(){...}
    ...
};
class  SpecialWindow:  public  Window {
public :
    
virtual   void  onResize() {
        static_cast
< Window > ( * this ).onResize();  // Error, 应该为Window::onResize(); 注意优先级相同、左结合
        
// 这里进行SpecialWindow的专属行为
    }
    ...
}; 

  错误的行,实际上对*this并无任何改变。改正后可以正确对*this调用函数,产生改变。(Effective C++ 条款27)

  7、如果可能,尽量避免转型,特别是在注重效率的代码中避免dynamic_cast。 

参考:http://www.cppreference.com/wiki/keywords/casting_comparison

转载于:https://www.cnblogs.com/younes/archive/2010/01/29/1658965.html

相关文章:

  • pycharm引入django
  • log
  • 360安全卫士升级致Win7/vista电脑不能上网
  • Leet Code OJ 219. Contains Duplicate II [Difficulty: Easy]
  • max(min)-device-width和max(min)-width的区别
  • 《掌控Windows SErver 2008 活动目录》 电子文档 下载 清华出版社
  • 深入浅出TensorFlow(七)TensorFlow计算加速
  • MapViewOfFile
  • mysql source 恢复 sql数据time_zone报错 已解决
  • 有效IT运维 效率提高 成本降低
  • IDC表示云计算占有率到2012年将翻一番
  • Linux操作系统下搭建VNC远程控制软件详尽教程
  • System Generator简介
  • UBUNTU下的LAMP搭建、配置、管理
  • DFS做题小结
  • ES6指北【2】—— 箭头函数
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【comparator, comparable】小总结
  • 【Leetcode】104. 二叉树的最大深度
  • AHK 中 = 和 == 等比较运算符的用法
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • JavaScript 基本功--面试宝典
  • JS数组方法汇总
  • SQLServer之创建显式事务
  • 从tcpdump抓包看TCP/IP协议
  • 工作中总结前端开发流程--vue项目
  • 技术发展面试
  • 聊聊directory traversal attack
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 微服务核心架构梳理
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 一个SAP顾问在美国的这些年
  • 一个完整Java Web项目背后的密码
  • 源码安装memcached和php memcache扩展
  • 《天龙八部3D》Unity技术方案揭秘
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​用户画像从0到100的构建思路
  • !!java web学习笔记(一到五)
  • # 飞书APP集成平台-数字化落地
  • #QT(一种朴素的计算器实现方法)
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (多级缓存)缓存同步
  • (二)Linux——Linux常用指令
  • (过滤器)Filter和(监听器)listener
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (十六)Flask之蓝图
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (转)C#调用WebService 基础
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (转)原始图像数据和PDF中的图像数据
  • .bat批处理(一):@echo off
  • .NET 材料检测系统崩溃分析
  • .Net 垃圾回收机制原理(二)
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?