http://blog.csdn.net/starryheavens/article/details/4617637

C 风格(C-style)强制转型如下:

(T) expression 或

T(expression) //函数风格(Function-style)

两种形式之间没有本质上的不同。

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

1.1 reinpreter_cast

用法:reinpreter_cast<type-id> (expression)

type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。

这个操作符能够在非相关的类型之间转换。操作结果只是简单的从一个指针到别的指针的值的二进制拷贝。在类型之间指向的内容不做任何类型的检查和转换。reinpreter_cast是特意用于底层的强制转型,导致实现依赖(就是说,不可移植)的结果。

int n=9;

// reinterpret_cast 仅仅是复制 n 的比特位到 d,因此d 包含无用值。

double d=reinterpret_cast<double & > (n);

1.2 const_cast

用法:const_cast<type_id> (expression)

用于修改类型的const或volatile属性。除了const 或volatile修饰之外,type_id和expression的类型是一样的,一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型,而C不提供消除const的机制(已验证)。

常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

1.3 static_cast

用法:static_cast < type-id > ( expression )

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它允许执行任意的隐式转换和相反转换动作。主要有如下几种用法:

1)用于基本数据类型之间的转换,如把int转换成char,non-const 对象转型为 const 对象(这里相反方向不可以,C++只有const_cast可以)。

2)把空指针转换成目标类型的指针。(之前的做法是用强制转换(type-id*))

3)把任何类型的表达式转换成void类型。

4)应用到类的指针上,它允许子类类型的指针转换为父类类型的指针(upercasting这是一个有效的隐式转换);也能够执行相反动作,即转换父类为它的子类(downcasting),这种转换的安全性需要开发人员来保证(主要是在非上下转型中)。

class Base {};
class Derived : public Base {};
Base *a = new Base;
Derived *b = NULL;
b = static_cast<Derived *>(a); //可以通过编译,但存在安全隐患(如访问//Derived的成员)

注意:

1.static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

2.在非基本类型或上下转型中,被转换的父类需要检查是否与目的类型相一致,否则,如果在两个完全不相干的类之间进行转换,将会导致编译出错。

1.4 dynamic_cast

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

当用于多态类型时(包含虚函数),它允许任意的隐式类型转换以及相反过程。不过,与static_cast不同,在后一种情况里(即隐式转换的相反过程),dynamic_cast根据RTTI信息检查操作是否有效。即在转换时dynamic_cast会检查转换是否能返回一个被请求的有效的完整对象。这种检查不是语法上的,而是真实情况的检查。检测在运行时进行,如果被转换的指针不是一个被请求的有效完整的对象指针,返回值为NULL。

先看RTTI相关部分,通常,许多编译器都是通过vtable找到对象的RTTI信息的,这也就意味着,如果基类没有虚函数,也就无法判断一个基类指针变量所指对象的真实类型, 这时候dynamic_cast只能用来做安全的转换(upercasting),如从派生类指针转换成基类指针,而这种转换其实并不需要dynamic_cast参与。

class Base { virtual dummy() {} };
class Derived : public Base {};
class Other{} ;
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的异常类型会被抛出:
Derived d3 = dynamic_cast<Derived &>(*b1); // succeeds
Derived d4 = dynamic_cast<Derived &>(*b2); // fails: exception thrown

注意:Base需要有虚函数,否则会编译出错。

1.5 小结

四种类型转换操作符对于隐式的类型转换没有必要。

static_cast在更宽上范围内可以完成映射,这种不加限制的映射伴随着不安全性。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时(基类需要包含虚函数),dynamic_cast具有类型检查的功能,牺牲了效率,但比static_cast安全。

[转]C++四种cast操作符的更多相关文章

  1. C++四种cast操作符

    C 风格(C-style)强制转型如下: (T) expression  或 T(expression) //函数风格(Function-style) 两种形式之间没有本质上的不同. 对于具有转换的简 ...

  2. C++的四种cast操作符的区别--类型转换(转)

    转自:     http://welfare.cnblogs.com/articles/336091.html Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 r ...

  3. C++的四种cast操作符的区别--类型转换

    Q:什么是C风格转换?什么是static_cast, dynamic_cast 以及 reinterpret_cast?区别是什么?为什么要注意? A:转换的含义是通过改变一个变量的类型为别的类型从而 ...

  4. C++中的四种转型操作符

    在具体介绍C++中的四种转型操作符之前,我们先来说说旧式转型的缺点: ①它差点儿同意将不论什么类型转换为不论什么其它类型,这是十分拙劣的.假设每次转型都可以更精确地指明意图,则更好. ②旧式转型难以辨 ...

  5. 面试问题之C++语言:说一说C++中四种cast转换

    C++中四种类型转换是:static_cast.dynamic_cast.const_cast.reinterpret_cast 1.const_cast 常量转换,用于将const变量转为非cons ...

  6. C++的四种强制转型形式:

    C++同时提供了四种新的强制转型形式(通常称为新风格的或C++风格的强制转型): const_cast(expression)dynamic_cast(expression)reinterpret_c ...

  7. 【转】C++四种类型转换方式

    C++四种类型转换方式 https://blog.csdn.net/lv_amelia/article/details/79483579 C风格的强制类型转换(Type Case)很简单,不管什么类型 ...

  8. C++中四种类型转换以及const_cast是否能改变常量的问题

    we have four specific casting operators:dynamic_cast, reinterpret_cast, static_cast and const_cast. ...

  9. [C++][操作符]四种显示转换操作符

    整理了C++ Primer中提到的四种显示转换,用思维导图写出来,是不是很清晰O(∩_∩)O.

随机推荐

  1. Android开发之计算器(一)界面设计之activity_main布局文件

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  2. php操作mysql数据库的基本类

    代码如下 复制代码 <?php$dbhost='localhost';$dbuser='root';$dbpass='123456';$dbname='products';$connect=my ...

  3. mysql基础三(视图、触发器、函数、存储过程、事务、防注入)

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 1.创建视图 -格式:CREATE ...

  4. Java从入门到精通——调错篇之ORACLE 打开PLSQL时提示ora-01033

    客户Oracle服务器进入PL/SQL Developer时报ora-01033:oracle initializationg or shutdown in progress 错误提示,应用系统无法连 ...

  5. MYSQL 配置slave故障

    之前为主从配置,后来分割成2个单实例.现在环境需要,重新配置为主从,之前参数都已配置好,直接启动,如下: mysql> change master to master_host='192.168 ...

  6. ASP.NET MVC 技术债务

    ASP.NET MVC 缓存.本地化和监控诊断 ASP.NET MVC 认证与授权 Entity Framework 创建数据模型

  7. .NET中 MEF应用于IOC

    IOC解释 IOC,控制反转的意思.所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓反转,你必须理解如果不反转,会怎么着,因为A必须要有B,才可 ...

  8. ASP.NET MVC +EasyUI 权限设计(一)开篇

    在前一段时间中,老魏的确非常的忙碌,Blog基本上没有更新了,非常的抱歉,那么在后面的时间中,老魏会尽量的抽时间来写的,可能时间上就不太富裕了.今天开始呢,老魏会和大家分享一下关于权限设计的有关文章, ...

  9. 关于WP8 微信分享的补充说明

    1.根据微信官方Demo完成相应功能. 2.在分享完后,从微信回来,需要进行 快速恢复. 3.在快速恢复中加入 RootFrame.Navigating += HandlerFotResetNavig ...

  10. 利用JavaScript获取页面文档内容

    JavaScript的document对象包含了页面的实际内容,所以利用document对象可以获取页面内容,例如页面标题.各个表单值. <!DOCTYPE html> <html ...