C++之static_cast, dynamic_cast, const_cast
转自:http://www.cnblogs.com/chio/archive/2007/07/18/822389.html
首先回顾一下C++类型转换:
C++类型转换分为:隐式类型转换和显式类型转换
又称为“标准转换”,包括以下几种情况:
1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。
double dval = 3.14159;
ival + dval;//ival被提升为double类型
2)一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型
int *pi = 0; // 0被转化为int *类型
ival = dval; // double->int
例外:void指针赋值给其他指定类型指针时,不存在标准转换,编译出错
3)将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型
cout << "The square root of 2 is " << sqrt(2) << endl;
//2被提升为double类型:2.0
4)从一个函数返回一个表达式,表达式类型与返回类型不一致:目标转换类型为函数的返回类型
{
return ival1 - ival2;
//返回值被提升为double类型
}
被称为“强制类型转换”(cast)
C 风格: (type-id)
C++风格: static_cast、dynamic_cast、reinterpret_cast、和const_cast..
|
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++ 的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、和const_cast。下面对它们一一进行介绍。
static_cast 用法:static_cast < type-id > ( expression )
说明:该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。
来源:为什么需要static_cast强制转换?
情况1:void指针->其他类型指针 情况2:改变通常的标准转换 情况3:避免出现可能多种转换的歧义 它主要有如下几种用法:
注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。 dynamic_cast 用法:dynamic_cast < type-id > ( expression )
说明:该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression也必须是一个指针,如果type-id是一个引用,那么expression也必须是一个引用。
来源:为什么需要dynamic_cast强制转换?
简单的说,当无法使用virtual函数的时候 典型案例: //Emplyee.h
class Employee { public: virtual int salary(); }; class Manager : public Employee class Programmer : public Employee 我们公司在开发的时候建立有如下类: class MyCompany
{ public: void payroll(Employee *pe); // ![]() }; void MyCompany::payroll(Employee *pe) 但是开发到后期,我们希望能增加一个bonus()的成员函数到W$公司提供的类层次中。 //Emplyee.h
class Employee { public: virtual int salary(); virtual int bonus(); }; class Manager : public Employee class Programmer : public Employee //Emplyee.cpp payroll()通过多态来调用bonus() class MyCompany
{ public: void payroll(Employee *pe); // ![]() }; void MyCompany::payroll(Employee *pe) 但是现在情况是,我们并不能修改源代码,怎么办?dynamic_cast华丽登场了! //Emplyee.h
class Employee { public: virtual int salary(); }; class Manager : public Employee class Programmer : public Employee //somewhere.cpp int Programmer::bonus() class MyCompany
{ public: void payroll(Employee *pe); // }; void MyCompany::payroll(Employee *pe) dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。 class Base
{ public: int m_iNum; virtual void foo(); }; class Derived:public Base void func(Base *pb) Derived *pd2 = dynamic_cast<Derived *>(pb); 在上面的代码段中, 另外,dynamic_cast还支持交叉转换(cross cast)。如下代码所示。 class Base
{ public: int m_iNum; virtual void f(){} }; class Derived1 : public Base }; class Derived2 : public Base }; void foo() pd1->m_iNum = 100; Derived2 *pd2 = static_cast<Derived2 *>(pd1); //compile error Derived2 *pd2 = dynamic_cast<Derived2 *>(pd1); //pd2 is NULL delete pd1; 在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用 dynamic_cast的转换则是允许的,结果是空指针。 reinpreter_cast 用法:reinpreter_cast<type-id> (expression)
说明:type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
该运算符的用法比较多。 const_cast 用法:const_cast<type_id> (expression)
说明:该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。 Voiatile和const类试。举如下一例: class B{
public: int m_iNum; } void foo(){ const B b1; b1.m_iNum = 100; //comile error B b2 = const_cast<B>(b1); b2. m_iNum = 200; //fine 上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。 |
C++之static_cast, dynamic_cast, const_cast的更多相关文章
- static_cast, dynamic_cast, const_cast
http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1 ...
- static_cast, dynamic_cast, const_cast探讨
转自:http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 ...
- 【C++专题】static_cast, dynamic_cast, const_cast探讨
首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...
- static_cast dynamic_cast const_cast reinterpret_cast总结对比
[本文链接] http://www.cnblogs.com/hellogiser/p/static_cast-dynamic_cast-const_cast-reinterpret_cast.html ...
- static_cast, dynamic_cast, const_cast 类型转换如何使用?
static_cast 用法:static_cast < type-id > ( expression ) 说明:该运算符把expression转换为type-id类型,但没有运行时类型检 ...
- static_cast, dynamic_cast, const_cast 三种类型转化的区别
强制转化四种类型可能很多人都常常忽略就象我一样,但是有时还是比较有用的.不了解的建议看看,一些机制我也不是十分了解,只是将一些用法写出来让大家看看. ...
- c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast
c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast [版权声明]转载请注明出处 http://www.cnblogs.c ...
- C++雾中风景11:厘清C++类型转换(static_cast,dynamic_cast,reinterpret_cast,const_cast)
C++是一门弱类型的语言,提供了许多复杂和灵巧类型转换的方式.笔者之前写的Python与Go都是强类型的语言,对这种弱类型的设计实在是接受无力啊~~ ( 生活所迫,工作还得写C++啊~~)C++语言提 ...
- static_cast 、const_cast、dynamic_cast、reinterpret_cast 关键字简单解释
static_cast .const_cast.dynamic_cast.reinterpret_cast 关键字简单解释: Static_cast 静态类型转换 ①用于类层次结构中基类(父类)和派生 ...
随机推荐
- 游标-----内存中的一块区域,存放的是select 的结果
游标-----内存中的一块区域,存放的是select 的结果 游标用来处理从数据库中检索的多行记录(使用SELECT语句).利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集 ...
- ICON图标文件解析
icon是一种图标格式,用于系统图标.软件图标等,这种图标扩展名为*.icon.*.ico.常见的软件或windows桌面上的那些图标一般都是ICON格式的. ICON文件格式比较简单,包含文件头段. ...
- 柯南君:看大数据时代下的IT架构(2)消息队列之RabbitMQ-基础概念详细介绍
一.基础概念详细介绍 1.引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用.通讯的问题而苦恼.挣扎?如果是,那么恭喜你,消息服务让你可以很轻松 ...
- BZOJ 1143 [CTSC2008]祭祀river(二分图匹配)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1143 [题目大意] 给出一张有向图,问最大不连通点集,连通具有传递性 [题解] 我们将 ...
- 「深入理解计算系统」从Hello World开始
从 hello world 开始 Table of Contents 1 程序源文件 2 程序源文件是什么 3 程序被编译 4 程序运行 4.1 读取命令 4.2 读取指令内容 4.3 执行过程 5 ...
- Saiku对Measure(指标)查询结果进行计算后显示的方法
在通过Saiku查询数据的时候,当需要改变查询结果的显示方式的时候,可以添加formatString属性,但是当需要计算查询结果的时候,则需要使用CellFormatter,使用方法如下: <M ...
- [置顶] 请听一个故事------>你真的认为iPhone只是一部手机?苹果惊天秘密!!
在网上看到的一篇小说,感觉有点意思,转载过来大家一起围观下,作者很幽默很风趣. 导读:iPhone的隐藏功能!Jobs的军方身份!图灵服毒自杀的传奇故事!中兴华为的神秘背景! 你真的认为iPhone只 ...
- android 三级菜单 BaseExpandableListAdapter
在网上搜了非常长时间.没有找到合适的Android三级菜单.所以就自己动手写了一个,主要使用了BaseExpandableList来实现,通过三个布局文件来完毕相应的菜单项,详细实现请參照下图. wa ...
- mac 版本号控制工具SmartSVN7.5.4(破解版)
SmartSVN7.5.4和破解工具,下载地址:http://download.csdn.net/detail/pearlhuzhu/7407319 操作步骤: 1.在MAC上选中smartsvn-m ...
- PostMessage和SendMessage的区别
1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数.而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息 ...
