一.static_cast

static_cast 只能用于良性转换,这样的转换风险较低,一般不会发生什么意外,如:

#include <iostream>
#include <cstdlib>
using namespace std; class Complex{
public:
Complex(double real = 0.0, double imag = 0.0): m_real(real), m_imag(imag){ }
public:
operator double() const { return m_real; } //类型转换函数
private:
double m_real;
double m_imag;
}; int main(){
//下面是正确的用法
int m = ;
Complex c(12.5, 23.8);
long n = static_cast<long>(m); //宽转换,没有信息丢失
char ch = static_cast<char>(m); //窄转换,可能会丢失信息
int *p1 = static_cast<int*>( malloc( * sizeof(int)) ); //将void指针转换为具体类型指针
void *p2 = static_cast<void*>(p1); //将具体类型指针,转换为void指针
double real= static_cast<double>(c); //调用类型转换函数 //下面的用法是错误的
float *p3 = static_cast<float*>(p1); //不能在两个具体类型的指针之间进行转换
p3 = static_cast<float*>(0X2DF9); //不能将整数转换为指针类型 return ;
}

二.const_cast

const_cast用来去掉表达式的 const 修饰或 volatile 修饰。换句话说,const_cast 就是用来将 const/volatile 类型转换为非 const/volatile 类型。如:

#include <iostream>
using namespace std; int main(){
const int n = ;
int *p = const_cast<int*>(&n);
*p = ;
cout<<"n = "<<n<<endl;
cout<<"*p = "<<*p<<endl; return ;
}

运行结果:

n = 100
*p = 234

&n用来获取 n 的地址,它的类型为const int *,必须使用 const_cast 转换为int *类型后才能赋值给 p。由于 p 指向了 n,并且 n 占用的是栈内存,有写入权限,所以可以通过 p 修改 n 的值。

至于为什么通过 n 和 *p 输出的值不一样呢?这是因为 C++ 对常量的处理更像是编译时期的#define,是一个值替换的过程,代码中所有使用 n 的地方在编译期间就被替换成了 100。换句话说,第 8 行代码被修改成了下面的形式:

cout<<"n = "<<<<endl;

这样以来,即使程序在运行期间修改 n 的值,也不会影响 cout 语句了。

三.reinterpret_cast

reinterpret_cast 这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,非常简单粗暴,所以风险很高

#include <iostream>
using namespace std; class A{
public:
A(int a = , int b = ): m_a(a), m_b(b){}
private:
int m_a;
int m_b;
}; int main(){
//将 char* 转换为 float*
char str[]="http://c.biancheng.net";
float *p1 = reinterpret_cast<float*>(str);
cout<<*p1<<endl;
//将 int 转换为 int*
int *p = reinterpret_cast<int*>();
//将 A* 转换为 int*
p = reinterpret_cast<int*>(new A(, ));
cout<<*p<<endl; return ;
}

运行结果:

3.0262e+29

个人感觉这个关键字很危险,所以不推荐使用.

四.dynamic_cast

dynamic_cast 用于在类的继承层次之间进行类型转换,它既允许向上转型(Upcasting),也允许向下转型(Downcasting)。向上转型是无条件的,不会进行任何检测,所以都能成功;向下转型的前提必须是安全的,要借助 RTTI 进行检测,所有只有一部分能成功。

有以下两点需要注意:

1).newType 和 expression 必须同时是指针类型或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、double、数组、类、结构体等)都不行。

2).对于指针,如果转换失败将返回 NULL;对于引用,如果转换失败将抛出std::bad_cast异常。

例:

#include <iostream>
using namespace std; class A{
public:
virtual void func() const { cout<<"Class A"<<endl; }
private:
int m_a;
}; class B: public A{
public:
virtual void func() const { cout<<"Class B"<<endl; }
private:
int m_b;
}; class C: public B{
public:
virtual void func() const { cout<<"Class C"<<endl; }
private:
int m_c;
}; class D: public C{
public:
virtual void func() const { cout<<"Class D"<<endl; }
private:
int m_d;
}; int main(){
A *pa = new A();
B *pb;
C *pc; //情况①
pb = dynamic_cast<B*>(pa); //向下转型失败
if(pb == NULL){
cout<<"Downcasting failed: A* to B*"<<endl;
}else{
cout<<"Downcasting successfully: A* to B*"<<endl;
pb -> func();
}
pc = dynamic_cast<C*>(pa); //向下转型失败
if(pc == NULL){
cout<<"Downcasting failed: A* to C*"<<endl;
}else{
cout<<"Downcasting successfully: A* to C*"<<endl;
pc -> func();
} cout<<"-------------------------"<<endl; //情况②
pa = new D(); //向上转型都是允许的
pb = dynamic_cast<B*>(pa); //向下转型成功
if(pb == NULL){
cout<<"Downcasting failed: A* to B*"<<endl;
}else{
cout<<"Downcasting successfully: A* to B*"<<endl;
pb -> func();
}
pc = dynamic_cast<C*>(pa); //向下转型成功
if(pc == NULL){
cout<<"Downcasting failed: A* to C*"<<endl;
}else{
cout<<"Downcasting successfully: A* to C*"<<endl;
pc -> func();
} return ;
}

运行结果:

Downcasting failed: A* to B*
Downcasting failed: A* to C*
-------------------------
Downcasting successfully: A* to B*
Class D
Downcasting successfully: A* to C*
Class D

C++语言基础(24)-四种类型转换运算符(static_cast、dynamic_cast、const_cast和reinterpret_cast)的更多相关文章

  1. C++中的四种类型转换运算符static_cast、dynamic_cast、const_cast和reinterpret_cast的使用

    1.上一遍讲述了C语言的隐式类型转换和显示类型转换,C语言之所以增加强制类型转换,就是为了强调转换的风险性,但这种强调风险的方式是比较粗放了,粒度比较大,它并没有表明存在什么风险,风险程度如何. 2. ...

  2. 引用、数组引用与指针引用、内联函数inline、四种类型转换运算符

    一.引用 (1).引用是给一个变量起别名 定义引用的一般格式:类型  &引用名 = 变量名: 例如:int a=1;  int  &b=a;// b是a的别名,因此a和b是同一个单元 ...

  3. 从零开始学C++之从C到C++(二):引用、内联函数inline、四种类型转换运算符

    一.引用 (1).引用是给一个变量起别名 定义引用的一般格式:类型  &引用名 = 变量名: 例如:int a=1; int  &b=a;// b是a的别名,因此a和b是同一个单元 注 ...

  4. C++语言中的四种类型转换

    1 引子 这篇笔记是根据StackOverflow上面的一个问题整理而成,主要内容是对C/C++当中四种类型转换操作进行举例说明.在之前其实对它们都是有所了解的,而随着自己在进行总结,并敲了一些测试示 ...

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

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

  6. [转]C++中四种类型转换符的总结

    C++中四种类型转换符的总结 一.reinterpret_cast用法:reinpreter_cast<type-id> (expression)    reinterpret_cast操 ...

  7. C++ 四种类型转换

    在写代码中经常会有很多的隐式类型转换或显式类型转换. 对于隐式的类型转换主要是放生在赋值的时候,讲变量赋值给不同类型的变量的时候就会发生类型转换,如果是宽化转换(即从占字节少的类型向占字节多的类型转换 ...

  8. c++ --> c++中四种类型转换方式

    c++中四种类型转换方式   c风格转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少缺点, 1)它可以在任意类型之间转换,比如你可以把一个指向const对象的指针转换成指向 ...

  9. 【C++】类型转换简述:四种类型转换方式的说明及应用

    本文主要简述在C++中四种类型转换的方式:static_cast.reniterpret_cast.const_cast和dynamic_cast. 在介绍C++类型转换方式之前,我们先来看看C语言的 ...

随机推荐

  1. iOS:在OC中调用JS脚本

    示例一:在webView中调用js脚本进行搜索 1.首先导入JavaScriptCore.framework这个框架 2.创建webView.设置代理.请求手机端百度 #import "Vi ...

  2. saltstack之mount和umount的用法

    线上很多服务器都需要挂载存储上的公共目录,并实现开机启动(/etc/fstab),比如web的静态文件共享目录,日志远程集中收集等. 一.批量挂载部分. 1.在node1上配置nfs服务器,有关nfs ...

  3. 【OpenGL】用OpenGL shader实现将YUV(YUV420,YV12)转RGB-(直接调用GPU实现,纯硬件方式,效率高)

    这段时间一直在搞视频格式的转换问题,终于最近将一个图片的YUV格式转RGB格式转换成功了.下面就来介绍一下: 由于我的工程是在vs2008中的,其中包含一些相关头文件和库,所以下面只是列出部分核心代码 ...

  4. C# Json 序列化和反序列化 工具类 Newtonsoft.Json.dll

    引用: Newtonsoft.Json.dll // 引用: using Newtonsoft.Json; using Newtonsoft.Json.Converters; // 定义 实体测试类 ...

  5. Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測

    事实上我也非常吃惊-居然写到第七篇了,我估计也就是四篇的内容,感觉非常奇妙,我也不会非常唠叨什么吖);    // 0001 );   // 0001 ); // 0001 这样我们才干监听到它们的碰 ...

  6. python 实现计算数独

    输入文件格式: 008309100900060004007504800036000540001000600042000970005907300600010008004608200 输出结果: yuan ...

  7. sdut 3-7 类的友元函数的应用

    3-7 类的友元函数的应用 Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 通过本题目的练习能够掌握类的友元函数的定义和使用方法 要求设计一个点类Poin ...

  8. 使用LNMP常见问题解答

    使用LNMP常见问题解答 一.LNMP的安装过程详解,注:绿色文字为注释,实际使用过程中没有. ##先要下载,并根据不同系统进行安装: wget -c http://soft.vpser.net/ln ...

  9. 云计算之路-阿里云上:启用Windows虚拟内存引发的CPU 100%故障

    今天上午11:35~11:40左右,由于负载均衡中的两台云服务器CPU占用突然飚至100%,造成网站5分钟左右不能正常访问,请大家带来了麻烦,请谅解! (上图中红色曲线表示CPU占用) 经过分析,我们 ...

  10. win10下JDK安装,配置环境变量后出现error:could not open '...jvm.cfg'

        分析: 大多是安装jdk的时候在注册表里注册过,打开注册表查看里面如下三个文件( Java Development Kit,Java Plug-in,Java Runtime Environm ...