static_cast,const_cast,dynamic_cast,reinterpret_cast
除非必要,尽量不要对变量进行强制转换。这是因为强制转换是存在风险的,但实际上在某种情况下,转型是必需的。
旧式C转型方式为(type)expression,即由一对小括号加上一个对象名称组成,而这种语法结构在C++的任何地方都有可能使用,这就无法直观的判断出是否是转型操作。
在C++中,旧式的C转型方式并非是唯一的选择方式,我们有了新式的类型转换,与老式的C转换允许将任何类型转换为任何其他类型这种释放拙劣的行为相比,C++引入的新式的转换方式可精确地指明转换的意图。
1.static_cast
static_cast<type-id>(expression) 该运算符把expression转换为type-id类型,但没有运行时的类型检查来保证转换的安全性。
int fistNum,secondNum; int fistNum,secondNum;
double res = (double)firstNum/sencondNum; //旧式转换 double res = static_cast<double>(firstNum)/secondNum; //新式转换
static_cast用途比较广泛,编译器隐式执行的任何类型转换都可使用其来实现,几种用法如下
(1)用于类层次结构中基类和子类之间指针或引用的转换
(2)进行上行转换(把子类的指针或引用转换成基类表示)是安全的
(3)把空指针转换成目标类型的空指针
(4)把任何类型的表达式转换成void类型
(5)static_cast不能转换掉expression的const,volitale或_unaligned属性
(6)进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。
(7)static_cast可用于将一个void*类型的指针强制转换为原来的指针类型,例如:
double d = 12;
void* p = &d;
double* pd = static_cast<double*>(p);
cout<<*pd<<endl; 输出结果12,说明转换后依然指向同一个地址。用于基本数据类型之间的转换。进行下行转换(把基类指针或引用转换成子类表示)
2.dynamic_cast
dynamic_cast<type-id>(expression) 该运算符把expression转换成type-id类型的对象。type-id必须是类的指针,类的引用或void*
如果type-id是类指针类型,那么expression也必须是一个指针
如果type-id是一个引用,那么expression也必须是一个引用
dynamic_cast要求派生类要有虚拟函数,否则编译不能通过
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
3.reinterpret_cast
reinterpret_cast<type-id>(expression)
type-id必须是一个指针,引用,算术类型,函数指针或者成员指针。例如:reinterpret_cast可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)
reinterpret_cast比static_cast更接近C的强制转换。它可以实现看起来没任何关系的两种类型的转换,当然它比static_cast危险
除非有必要,否则在C++编程中应尽量避免使用reinterpret_cast
static_cast在编译时使用类型信息执行转换,在转换执行必要的检测(诸如越界计算,类型检查)时,其操作数相对是安全的。reinterpret_cast仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换,例如:
int n = 9;
double d = static_cast<double>(n);
将一个变量从int转换到double,这种类型的二进制表达式是不同的。要将整数9转换到双精度整数9,static_cast需要正确地为双精度d补足比特位,其结果为9.0,而reinterpret_cast不会有这样的操作。
4.const_cast
const_cast<type-id>(expression) 主要用来修改类型的const或volatile属性,在使用过程中,除了const或volatile修饰之外,type-id和expression的类型是一样的。
尽管类型转换操作符的方式没有非常明显的优势,但还是建议在C++工程中尽量避免C风格的类型转换。使用类型转换操作符的方式进行类型转换,是一种好的编码习惯
由于强制类型转换无所不能,所以无形中会给C++程序带来很大的安全隐患。因此建议在C++代码中使用C++提供的除reinterpret_cast以外的3种转换方式。除非必要,否则应禁止使用强制类型转换和reinterpret_cast;
static_cast,const_cast,dynamic_cast,reinterpret_cast的更多相关文章
- c++强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)
static_cast <typeid>(exdlvssion) static_cast 很像 C 语言中的旧式类型转换.它能进行基础类型之间的转换,也能将带有可被单参调用的构造函数或用户 ...
- C++提供的四种新式转换--const_cast dynamic_cast reinterpret_cast static_cast
关于强制类型转换的问题,许多书都讨论过,写的最具体的是C++之父的<C++的设计和演化>. 最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_c ...
- static_cast、dynamic_cast reinterpret_cast
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的<C++ 的设计和演化>.最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_ ...
- c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast
c++ 数据类型转换: static_cast dynamic_cast reinterpret_cast const_cast [版权声明]转载请注明出处 http://www.cnblogs.c ...
- static_cast、dynamic_cast、reinterpret_cast、const_cast以及C强制类型转换的区别
static_cast 1. 基础类型之间互转.如:float转成int.int转成unsigned int等 2. 指针与void*之间互转.如:float*转成void*.CBase*转成void ...
- C++强制类型转换:static_cast、dynamic_cast、const_cast、reinterpret_cast
1. c强制转换与c++强制转换 c语言强制类型转换主要用于基础的数据类型间的转换,语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2 ...
- C++雾中风景11:厘清C++类型转换(static_cast,dynamic_cast,reinterpret_cast,const_cast)
C++是一门弱类型的语言,提供了许多复杂和灵巧类型转换的方式.笔者之前写的Python与Go都是强类型的语言,对这种弱类型的设计实在是接受无力啊~~ ( 生活所迫,工作还得写C++啊~~)C++语言提 ...
- C++的类型转换:static_cast、dynamic_cast、reinterpret_cast和const_cast
在C++中,存在类型转换,通常意味着存在缺陷(并非绝对).所以,对于类型转换,有如下几个原则:(1)尽量避免类型转换,包括隐式的类型转换(2)如果需要类型转换,尽量使用显式的类型转换,在编译期间转换( ...
- static_cast、dynamic_cast、reinterpret_cast、和const_cast
关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的<C++ 的设计和演化>.最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_ ...
随机推荐
- Android 常用代码大集合 [转]
[Android]调用字符串资源的几种方法 字符串资源的定义 文件路径:res/values/strings.xml 字符串资源定义示例: <?xml version="1.0&q ...
- java中表示二进制、八进制、十进制、十六进制,double、float、整型
java里不能这样表示二进制,只能是 8,10,16进制 8: 前置 0 10: 不需前置 16: 前置 0x 或者 0X double:2 ...
- 一个C/C++结构体初始化有趣的现象
我们知道C语言当中结构可以使用{}进行初始化,例如有结构体定义如下: typedef struct type_t { int a; int b; int c; int d; }type_t; 我们可以 ...
- JavaScript创建对象的模式
/** * Created by W_YH on 2016/3/14. */ /* 对象的创建方式 */ //------->第一种创建方式------创建Object的实例 var perso ...
- MySQL-python 1.2.3 for Windows and Python 2.7, 32bit and 64bit versions -(亲测可用)
MySQL-python 1.2.3 for Windows and Python 2.7, 32bit and 64bit versions - See more at: http://www.co ...
- Set无序怎么办?
在JAVA中,提供多种不同的结构来组织对象,Set(集合)是其中的一种,本身是一个接口,其迭代时的顺序取决于其具体实现. 典型的实现包括: HashSet:哈希表是通过使用称为散列法的机制来存储信息的 ...
- 实现ModelDriver接口的功能
ModelDriver接口 来自com.opensymphony.xwork2.ModelDriven.是xwork-2.1.2-750.jar包的东西. 下面是源码: package com.ope ...
- php代码20个实用技巧 ------ 转发自菜鸟教程
1.不要实用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点:它首先查找指定的php包含路径,然后查找当前目录,因此会检查过 ...
- 微博发布效果jq版
大家都看过新浪微博的发状态功能,我模拟了一下类似的效果,包括发布时间,删除效果等.代码如下: <!DOCTYPE HTML> <html> <head> <m ...
- shell命令实战详解
1.解析路径获取文件名和目录名. 获取文件名 #awk解法:用“/”做分隔符,然后打印出最后的那一部分. resFile=`echo /tmp/csdn/zhengyi/test/adb.l ...