C++类型转换:static_cast、reinterpreter_cast、dynamic_cast、const_cast

C++支持C语言的强制类型转换,并提供了四种应对各种的强制类型函数,以下对C++的强制类型转换做简单介绍。

1.C语言风格强制类型转换

1 TypenameB b;
2 TypenameA a=(TypenameA)b;

C语言风格类型强制转换存在较多安全隐患,例如:

1)把一个指向 const 对象的指针转换成指向非 const 对象的指针;

2)把一个指向基类对象的指针转换成指向一个派生类对象的指针;

3)C 风格的转换不容易查找,他由一个括号加上一个标识符组成, 而这样的东西在 c++程序里一大堆。
因此,C++提供了四种转换类型。

2.C++ 四种强制类型转换

 static_cast 静态类型转换

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:

1)用于基类(父类)和派生类(子类)之间指针或引用的转换。

进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。

2)用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。基本转换的安全性由开发者保证。

3)把空指针转换成目标类型的空指针、把任何类型的表达式转换成void类型。

注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。

1 double a=1.12;
2 int b= static_cast<int> (a); //c++的新式的类型转换运算符  
3 char *p1 = "hello" ;//指针与void指针转换
4 int *p2 = nullptr;
5 p2 = (int *)p1;
6 //p2 = static_cast<int *> (p1); ///不能转换指针类型“static_cast”: 无法从“char *”转换为“int *”

reinterpreter_cast 重解释类型转换

可以用于任意类型指针之间的转换,没有安全性检测。

1 int *a = new int;
2 double *b = reinterpret_cast<double *>(a);

const_cast 去掉const属性转换

1)常量指针被转化成非常量的指针,并且仍然指向原来的对象; 
2)常量引用被转换成非常量的引用,并且仍然指向原来的对象; 
3)const_cast一般用于修改指针。如const char *p形式;

1 const double a = 7;
2 const double* p = &a;
3 double* q = const_cast<double*>(p);
4 *q = 20; //通过q写值是未定义的行为
5 cout << *q<<"   "<<a<<"   "<<*p << endl;

运行输出

20   7   20

强制转换后,*q 与*p不再指向a,*q 与*p依然指向同一地址空间,且能够通过*q修改地址对应变量的值,但*p不能。

1 double a = 7;
2 const double& p = a;
3 double& q = const_cast<double&>(p);
4 q = 20; //通过q写值是未定义的行为
5 cout << q<<"   "<<a<<"   "<<p << endl;

运行输出

20   20   20

强制转换后,q 与p依然指向a,且能够通过q修改地址对应变量的值,但p不能。

dynamic_cast 动态类型转换

1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。

2)不能用于内置的基本数据类型的强制转换。

3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。

4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。

dynamic_cast用于类继承层次间的指针或引用转换。主要还是用于执行“安全的向下转型(safe downcasting)”,也即是基类对象的指针或引用转换为同一继承层次的其他指针或引用。至于“先上转型”(即派生类指针或引用类型转换为其基类类型),本身就是安全的,尽管可以使用dynamic_cast进行转换,但这是没必要的, 普通的转换已经可以达到目的,毕竟使dynamic_cast是需要开销的

posted @   hik_老鬼  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示