转自c/c++强制类型转换

Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意?

A:转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:

代码:

int i;

double d;

i = (int) d;或者:i = int (d);

对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast', 'static_cast',
'dynamic_cast' 和 'const_cast',目的在于控制类(class)之间的类型转换。

代码:
  • reinterpret_cast<new_type>(expression)
  • dynamic_cast<new_type>(expression)
  • static_cast<new_type>(expression)
  • const_cast<new_type>(expression)

1 reinterpret_cast



reinterpret_cast 转换一个指针为其它类型的指针。它也允许从一个指针转换为整数类型。反之亦然。(译注:是指针具体的地址值作为整数值?)

这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。如果情况是从一个指针到整型的拷贝,内容的解释是系统相关的,所以任何的实现都不是方便的。一个转换到足够大的整型能够包含它的指针是能够转换回有效的指针的。

代码:

class A {};

class B {};

A * a = new A;

B * b = reinterpret_cast<B *>(a);

reinterpret_cast  就像传统的类型转换一样对待所有指针的类型转换。



2 static_cast



static_cast 允许执行任意的隐式转换和相反转换动作。(即使它是不允许隐式的)

意思是说它允许子类类型的指针转换为父类类型的指针(这是一个有效的隐式转换),同时,也能够执行相反动作:转换父类为它的子类。

在这最后例子里,被转换的父类没有被检查是否与目的类型相一致。

代码:

class Base {};

class Derived : public Base {};



Base *a    = new Base;

Derived *b = static_cast<Derived *>(a);

static_cast  除了操作类型指针,也能用于执行类型定义的显式的转换,以及基础类型之间的标准转换:

代码:

double d = 3.14159265;

int    i = static_cast<int>(d);



3 dynamic_cast

dynamic_cast只用于对象的指针和引用。当用于多态类型时,它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(注:即隐式转换的相反过程),dynamic_cast会检查操作是否有效。也就是说,它会检查转换是否会返回一个被请求的有效的完整对象。

检测在运行时进行。如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL.

代码:

class Base { virtual dummy() {} };

class Derived : public Base {};



Base* b1 = new Derived;

Base* b2 = new Base;



Derived* d1 = dynamic_cast<Derived *>(b1);          // succeeds

Derived* d2 = dynamic_cast<Derived *>(b2);          // fails: returns 'NULL'



如果一个引用类型执行了类型转换并且这个转换是不可能的,一个bad_cast的异常类型被抛出:

代码:

class Base { virtual dummy() {} };

class Derived : public Base { };



Base* b1 = new Derived;

Base* b2 = new Base;



Derived d1 = dynamic_cast<Derived &*>(b1);          // succeeds

Derived d2 = dynamic_cast<Derived &*>(b2);          // fails: exception thrown



4 const_cast



这个转换类型操纵传递对象的const属性,或者是设置或者是移除:

代码:

class C {};

const C *a = new C;



C *b = const_cast<C *>(a);

其它三种操作符是不能修改一个对象的常量性的。

注意:'const_cast'也能改变一个类型的volatile qualifier。


 C++的四种强制转型形式每一种适用于特定的目的: 



  ·dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。

    

    ·static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等),它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它最接近于C-style的转换。

    

  ·const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。 



  ·reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。

  

c/c++强制类型转换的更多相关文章

  1. java中强制类型转换

    在Java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需 ...

  2. C++强制类型转换

    C语言强制类型转换过于粗暴,任意类型之间都可以进行转换,编译很难判断其正确性; 难于定位,在源码中无法快速定位所有使用强制类型转换的语句. C++将强制类型转换分为4种不同的类型:static_cas ...

  3. java提高篇(十一)-----强制类型转换

    在java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需 ...

  4. JavaScript学习10 JS数据类型、强制类型转换和对象属性

    JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...

  5. C++强制类型转换操作符 dynamic_cast

    dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用. >>>>>>>>>>>编译器的RTTI设 ...

  6. C++强制类型转换操作符 const_cast

    const_cast也是一个强制类型转换操作符.<C++ Primer>中是这样描述它的: 1.将转换掉表达式的const性质. 2.只有使用const_cast才能将const性质性质转 ...

  7. C++强制类型转换操作符 static_cast

    static_cast是一个强制类型转换操作符.强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast.dynamic_cast.const_cast.reinterpert ...

  8. Js里面的强制类型转换

    js 和 PHP语言一样是弱类型语言.近期我也在看C语言,并没有传说中那么难,既是书中一再强调的指针部分,也没有那么夸张.至少是理论和语法理解起来不是很难.看起来凡是什么东西,不要总是被别人的话迷惑了 ...

  9. c语言强制类型转换

    一.强制类型转换 printf("3/2+100.5=%f",3/2+100.5);//100.5错误表达 printf ("    (float)3/(float)2 ...

  10. 数据类型/强制类型转换 和运算符---标识符规则/关键字 a++和++a区别

    3.2关键字都是小写,TRUE FALSE NULL都不是Java关键字 3.3数据类型 变量相当于一个有名称的容器,该容器用于装各种不同类型的数据 Java类型分为2种 基本类型: 引用类型: 基本 ...

随机推荐

  1. 2013年7月28日web前端学习笔记-------head相关标签应用

    7月份快过完了.趁周日写写学过觉得有用的东西. 1.缩略图的展示问题,不要以为缩略图设置了width,height,就是缩略图了.比如一个300kb的500*500原始图片,用户请求web服务器后,展 ...

  2. ios Swift 算法

    // Playground - noun: a place where people can play import Cocoa var nums = Int[]() ... { nums.appen ...

  3. 第五十七篇、AVAssetReader和AVAssetWrite 对视频进行编码

    AV Foundation提供了直接处理媒体样本的低级功能,其中需要使用的两个重要的类,AVAssetReader和AVAssetWrite,AVAssetReader用于从AVAsset资源读取媒体 ...

  4. VirtualDesktop与Desktops多窗口程序的对比

    在Linux系统下,有着原生的虚拟桌面程序,windows下面则没有提供. windows相对linux好的就是其良好的生态圈. Virtual Desktop类似linux的虚拟桌面程序,可以支持多 ...

  5. OpenGL8-直接分配显存-极速绘制(2)

    视频教程请关注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440/*** OpenGL8-直接分配显存-极速绘制(Opengl1 ...

  6. 用css3做标签

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. DB2 connection

    1.DB2 connection-----DB2连接方式 2.开放应用层----type way 4 ==共享 3.本地本地之间访问----type way 2 JDBC SD---sysplex d ...

  8. 2013山东省“浪潮杯”省赛 A.Rescue The Princess

    A.Rescue The PrincessDescription Several days ago, a beast caught a beautiful princess and the princ ...

  9. pthread 实现生产者消费者问题

    经典的生产者消费者问题,在这里用信号量和互斥量来实现生产和消费者模型   #include<cstdlib> #include<cstdio> #include<unis ...

  10. 使用UDP进行数据发送的实例一

    首先如果TCP学过以后,再看UDP进行数据传输也是大同小异的,只是用到的类不同 UDP进行传输需要DataSocket和Datapacket类,Datapacket叫数据报,每一个数据报不能大于64k ...