c++ 数据类型转换: static_cast、dynamic_cast、reinterpret_cast和const_cast
【目录】
引言
static_cast 定义
dynamic_cast 定义
举例:下行转换(把基类的指针或引用转换成子类表示)
举例:上行转换(把子类的指针或引用转换成基类表示)
举例: static_cast 用于基本类型之间、基本类型指针和空指针间的转换
reinterpret_cast 定义
举例:reinterpret_cast用法
const_cast 定义
举例:const_cast用法
总结
c语言中我们经常使用类似于 int a =(int)3.14等这种强制类型转换
标准c++的类型转换符:static_cast 、dynamic_cast、 reindivter_cast、 const_cast, 以下分别介绍他们的用法以及举例说明
以下代码编译运行环境:codeblock with gcc in win7(x64)
一、static_cast
用法:
static_cast < type-id > (exdivssion)
该运算符把exdivssion转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast 不能转换掉exdivssion的const、volitale、或者__unaligned属性。
msdn官方解释:http://msdn.microsoft.com/en-us/library/c36yw7x9(v=vs.80).aspx
二、dynamic_cast
用法:
dynamic_cast < type-id > ( exdivssion )
该运算符把exdivssion转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;
如果type-id是类指针类型,那么exdivssion也必须是一个指针,如果type-id是一个引用,那么exdivssion也必须是一个引用。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast 的效果是一样的;
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast 更安全。
msdn官方解释:http://msdn.microsoft.com/en-us/library/cby9kycs(v=vs.80).aspx
举例:下行转换(把基类的指针或引用转换成子类表示)
需要注意的是如果基类中不含虚函数,dynamic_cast 下行转换编译会出错
#include<iostream>
using namespace std;class father
{
public:void fun1(){cout<<"this is father fun1 call\n";}virtual void fun(){cout<<"this is father fun call\n";}
};class son: public father
{
public:void fun2(){cout<<"this is son fun2 call\n";}void fun(){cout<<"this is the son fun call\n";}int k;
};int main()
{father *pf, f;son *ps, s;pf = &f;// 基类的指针指向基类对象ps = static_cast<son *>(pf);//这种转换是不安全的,行为是不确定的if(ps != NULL){ps->fun(); //在本文编译环境下,执行父类的fun//本文编译环境下,一下语句可以执行ps->fun2();ps->k = 1;}ps = dynamic_cast<son *>(pf);//转换后ps = NULLif(ps == NULL)cout<<"dynamic_cast: ps = NULL\n";cout<<"-----------------------------------------------------------------\n";pf = &s; //基类指针开始指向子类对象//此时,两种转换都是安全的ps = static_cast<son *>(pf);if(ps != NULL){ps->fun();ps->fun2();ps->k = 1;}ps = dynamic_cast<son *>(pf);//转换后ps = NULLif(ps != NULL){ps->fun();ps->fun2();ps->k = 2;}
}
结果:
举例:上行转换(把子类的指针或引用转换成基类表示)
//类定义同上
int main()
{father *pf, f;son *ps, s;ps = &s;// 子类的指针指向子类对象//此时两种转换都是安全的pf = static_cast<father *>(ps);if(pf != NULL){pf->fun();}pf = dynamic_cast<father *>(ps);if(pf != NULL){pf->fun();}}
举例: static_cast 用于基本类型之间、基本类型指针和空指针间的转换(不能用于基本类型指针之间转换)。
注意:基本类型由于表示数值范围的不同,因此需要用户保证转换的安全。另外dynamic_cast不能用于此类转换
int main()
{//基本类型间的转换,需要用户保证安全int a = 1000;char c = static_cast<char>(a);//不安全,1000超过了char的表示范围cout<<c<<endl;//输出空a = 49;c = static_cast<char>(a);//安全,输出字符‘1’cout<<c<<endl;//c = dynamic_cast<char>(a); 错误cout<<"-----------------------------------------------------------------\n";//void *和基本类型指针的转换,需要用户保证转换安全a = 49;void *pv;pv = &a;int *pi = static_cast<int *>(pv);//void * 转换为int *cout<<*pi<<endl; //输出49//pi = dynamic_cast<int *>(pv); 错误char *pc = static_cast<char *>(pv);//void *转char*cout<<*pc<<endl;//输出字符‘1’void *pv2 = static_cast<void *>(pc);// char * 转void *cout<<*((char *)pv2)<<endl;输出字符‘1’
}
三、reinterpret_cast
用法:
reinterpret_cast<type-id> (exdivssion)
reinterpret_cast运算符是用来处理无关类型之间的转换;它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。按照reinterpret的字面意思“重新解释”,即对数据的比特位重新解释。
IBM的C++指南 里明确告诉了我们reinterpret_cast可以,或者说应该在什么地方用来作为转换运算符:
- 从指针类型到一个足够大的整数类型
- 从整数类型或者枚举类型到指针类型
- 从一个指向函数的指针到另一个不同类型的指向函数的指针
- 从一个指向对象的指针到另一个不同类型的指向对象的指针
- 从一个指向类函数成员的指针到另一个指向不同类型的函数成员的指针
- 从一个指向类数据成员的指针到另一个指向不同类型的数据成员的指针
总结来说:reinterpret_cast用在任意指针(或引用)类型之间的转换;以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。
注意:static_cast 不能转换掉exdivssion的const、volitale、或者__unaligned属性。
msdn官方解释:http://msdn.microsoft.com/en-us/library/e0w9f63b(v=vs.80).aspx
举例:reinterpret_cast用法
int main()
{int a = 49;int *pi = &a;char *pc = reinterpret_cast<char*>(pi);//int * 到char *,用户自己安全cout<<*pc<<endl; //输出字符"1"unsigned long b = reinterpret_cast<unsigned long>(pc);//char * 转 unsigned longcout<<b<<endl;//输出pc指向地址(即a的地址)对应的整数int *pi2 = reinterpret_cast<int *>(b);//unsigned long 转 int*cout<<*pi2<<endl; //输出49
}
四、const_cast
用法:
const_cast<type-id> (exdivssion)
该运算符用来修改类型的const、volatile、__unaligned属性。除了const 、volatile、__unaligned修饰之外, type_id和exdivssion的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
msdn官方解释:http://msdn.microsoft.com/en-us/library/bz6at95h(v=vs.80).aspx举例:const_cast用法
int main()
{const int a = 100;int *b = const_cast<int *>(&a);//const int * 转int *cout<<*b<<endl; //输出100cout<<&a<<" "<<b<<endl; //两者值相同,表明b指向a的地址,只是const属性变了
}
总结:
类指针或引用的上行转换static_cast 和 dynamic_cast 都可以
类指针或引用的下行转换用dynamic_cast并且判断转换后是否为空
基本数据类型之间的转换用static_cast, 但是由于数值范围的不同,需要用户保证转换的安全性
不同类型之间的指针或引用的转换用reinterpret_cast,它的本质是对指向内存的比特位的重解释
消除数据的const、volatile、__unaligned属性,用const_cast
参考:C++数据类型转换
c++ 数据类型转换: static_cast、dynamic_cast、reinterpret_cast和const_cast相关推荐
- C/C++中的数据类型转换()/static_cast/dynamic_cast/const_cast/reinterpret_cast
文章目录 前言 数据类型自动转换 C语言中的强制类型转换 C++中的强制类型转换 static_cast dynamic_cast const_cast reinterpret_cast 强转关键字的 ...
- c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast
c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast [版权声明]转载请注明出处 http://www.cnblogs.co ...
- 类型转换static_cast,dynamic_cast,const_cast,reinterpret_cast等
一.隐式类型转换 系统自动进行,不需要程序开发人员介入. int m = 3 +45.6; //把小数部分截掉,也属于隐式类型转换的一种行为. doublen = 3 +45.6; 二.显示类型转换( ...
- C++类型转换(static_cast,dynamic_cast,const_cast和reinterpret_cast)
一.概述 类型转换(cast)是将一种数据类型转换成另一种数据类型.例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型(即 隐式转换 ).转换是非常有用的,但是它也会带来一 ...
- 显式强制类型转换static_cast, dynamic_cast, const_cast, reinterpret_cast
显式强制类型转换(cast)包括以下操作符: static_cast, dynamic_cast, const_cast, reinterpret_cast,对各种显式类型转换解释: static_ ...
- static_cast,dynamic_cast,reinterpret_cast,const_cast的使用
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的<C++ 的设计和演化>.最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_ ...
- 【C++ 语言】类型转换 ( 转换操作符 | const_cast | static_cast | dynamic_cast | reinterpret_cast | 字符串转换 )
文章目录 I . const_cast 转换操作符 II . static_cast 转换操作符 III . dynamic_cast 转换操作符 IV . reinterpret_cast 转换操作 ...
- c++类型转换:static_cast, dynamic_cast,const_cast和reinterpret_cast
static_cast 用法:static_cast < type-id > ( expression ) 说明:该运算符把expression转换为type-id类型,但没有运行时类型检 ...
- static_cast, dynamic_cast, reinterpret_cast, const_cast区别比较
转载于:http://www.cnblogs.com/jerry19880126/archive/2012/08/14/2638192.html 隐式转换(implicit conversion) s ...
- C++类型转换运算符(dynamic_cast, const_cast, static_cast)
C++类型转换运算符 1. dynamic_cast 2. const_cast 3. static_cast 4. reinterpret_cast 摘自以下图书: <C++ Primer P ...
最新文章
- linux如何设置awesome字体,Awesome简单配置
- 关于varchar(max), nvarchar(max)和varbinary(max)
- 烂泥:centos安装及配置DNS服务器
- hdfs源码分析第一弹
- 使用OpenCV与百度OCR C++ SDK实现文字识别
- 交换机端口镜像(锐捷)
- sudo详细介绍...
- python 相关系数_python如何计算相关系数与协方差
- 《手机测试Robotium实战教程》——导读
- Delphi 记录类型- 结构指针
- Struts2之初识篇(一)——与struts的区别和基本配置
- VBS表白代码以及一些注意事项
- 【极速下载】gradle各版本快速下载地址大全
- 启动jar包报错: 找不到或无法加载主类
- ha rose server安装 sql_Rose HA for SQL2008的安装之一
- MAC和IP地址伪造发包
- 位置不可用——文件或目录损坏且无法读取
- FeignClient中每一个@RequestParam 都要设置value,否者报错
- 【无标题】PHP小皮中出现拒绝访问(使用密码:YES)
- 深入分析小程序与H5的区别
热门文章
- 随手笔记:我的架构师之路--沈剑 到家集团技术委员会主席快狗打车CTO
- yum更新php版本,yum php版本太低怎么办
- 戴尔服务器安装centos7修改网卡名,Centos7.6修改网卡名称为之前的eth形式
- Windows IO 性能简单测试
- 解决datagridview 横向的scrollbar不显示
- LeetCode-185 : sql分组排序再取前几位
- oracle的globalname后缀,在Oracle 11g下查看数据库的global_name
- VB.NET水晶报表控件经验总结
- Ubuntu Server 如何校对时钟(通过NTP)
- php jquery 实例教程,php jquery 多文件上传简单实例