C++风格的强制类型转换:const_caststatic_castdynamic_castreinterpret_cast

使用:xxx_cast<type-id> (expression)

const_cast

  • 说明:该运算符用来修改类型的const或volatile属性。
 1 class TestA
 2 {
 3 public:
 4     TestA() { }
 5 public:
 6     int m_data;
 7 };
 8
 9 void foo()
10 {
11     const TestA ta;
12     //ta1.m_data = 100;    //编译错误
13
14     TestA *pTa = const_cast<TestA*>(&ta);
15     pTa->m_data = 200;     //OK
16
17     TestA &taTmp = const_cast<TestA&>(ta);
18     taTmp.m_data = 300;    //OK
19 }
20
21 int main( int argc, char * argv[] )
22 {
23     foo();
24     return 0;
25 }

 

static_cast

  • 说明:无条件强制转换,没有在运行时进行类型检查来保证转换的安全性,static_cast也不能去掉类型的const、volitale属性。
  • 场景:
  1. 基类和子类之间转换:进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
  2. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等。
  3. 把空指针转换成目标类型的空指针。
  4. 把任何类型的表达式转换成void类型。
 1 void foo()
 2 {
 3     int n = 6;
 4     char c = static_cast<char>(n);          // 基本类型转换
 5     double d = static_cast<double>(n);
 6     float f = static_cast<float>(n);
 7
 8     int *pn = &n;
 9     //double *d = static_cast<double*>(&n)  //无关类型指针转换,编译错误
10     void *p = static_cast<void*>(pn);       //任意类型转换成void类型
11 }
12
13 int main( int argc, char * argv[] )
14 {
15     foo();
16     return 0;
17 }

dynamic_cast

  • 说明:type-id必须是类的指针、类的引用或者void*,运行时会进行类型安全检查(转换失败返回NULL)。
  • 场景:
  1. 基类和子类之间转换,上行和下行转换都是安全的。
  2. 基类必须要有虚函数。
  3. 交叉转换(相同基类的不同子类之间的转换),但结果是NULL。
 1 #include <string.h>
 2 #include <iostream>
 3
 4 using namespace std;
 5
 6 class BaseClass
 7 {
 8 public:
 9     int m_data;
10     virtual void btest(){}; //基类必须有虚函数
11 };
12
13 class DerivedClass : public BaseClass
14 {
15 public:
16     char m_arr[100];
17     void dtest(){};
18 };
19
20 void foo()
21 {
22     BaseClass* pb = new DerivedClass();
23     DerivedClass *pd1 = static_cast<DerivedClass *>(pb);   //子类->父类,静态类型转换,正确但不推荐
24     DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb);  //子类->父类,动态类型转换,正确
25
26     BaseClass* pb2 = new BaseClass();
27     DerivedClass *pd3 = static_cast<DerivedClass *>(pb2);  //父类->子类,静态类型转换,危险!
28     //strcpy(pd3->m_arr, "0123456789");                    //访问子类m_arr成员越界,造成运行时错误。
29
30     DerivedClass *pd4 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全。结果为NULL。
31     if (NULL == pd4)
32     {
33         cout << "null == pd4" << endl;
34     }
35 }
36
37 int main( int argc, char * argv[] )
38 {
39     foo();
40     return 0;
41 }

reinterpret_cast

  • 说明:仅仅重新解释类型,但没有做字节对齐。
  • 场景:最普通的用途就是在函数指针类型之间进行转换,但是很难保证移植性。
 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 class TestA
 6 {
 7 public:
 8     int m_a;
 9 };
10
11 class TestB
12 {
13 public:
14     int m_b;
15 };
16
17 class TestC : public TestA, public TestB
18 {};
19
20 void foo()
21 {
22     TestC tc;
23
24     cout << "&tc = 0x" << &tc << endl;
25     cout << "reinterpret_cast<TestB*>(&tc) = 0x" << reinterpret_cast<TestB*>(&tc) << endl;
26     cout << "static_cast<TestB*>(&tc) = 0x" << static_cast<TestB*>(&tc) << endl;
27 }
28
29 int main( int argc, char * argv[] )
30 {
31     foo();
32     return 0;
33 }

结果:

static_cast转换之后结果 - reinterpret_cast转换之后的结果 = 4(即该测试类中的字节对齐长度)。

说明:static_cast在进行上行转换是安全的,static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址,而reinterpret_cast则不会做这层转换。

总结

  • const_cast:去const或volatile属性时用到。
  • static_cast:基本类型转换(不包括指针类型)时用到。
  • daynamic_cast:基类与子类的指针(或引用)互相转换时用到。
  • reinterpret_cast:不同类型的指针类型转换(如:函数指针类型之间进行转换),慎用。

参考

  • http://baike.baidu.com/view/1745221.htm
  • http://baike.baidu.com/view/1745207.htm
  • http://baike.baidu.com/view/1745213.htm
  • http://baike.baidu.com/view/1263731.htm
  • http://www.cnblogs.com/goodhacker/archive/2011/07/20/2111996.html

(完)

转载于:https://www.cnblogs.com/helloamigo/p/3506304.html

[C++] C++风格的强制类型转换探讨相关推荐

  1. static_cast与c风格的强制类型转换比较

    class A {int a; };class B {int b; };class C : public A {int c; };int main() {B b;C c;A* p1 = (A*) &a ...

  2. C++风格的类型转换操作符与C风格的强制类型转换

    很多人对C++中的几个类型转换操作符是有些陌生的,并且代码中类型转换也从来都是用C风格的强制类型转换.而且会有些人认为使用这些操作符麻烦,不方便或者没必要.下面是对网上一些资料的总结,主要分析一下两种 ...

  3. 谁说 C++ 的强制类型转换很难懂?

    作者 | 樱雨楼 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 在上篇与中篇中,我们讨论了隐式类型转换及其与函数重载之间的相关话题.本篇将要讨论的即为类型转换的另一大分支--强制类型转 ...

  4. 深入理解C++中五种强制类型转换的使用场景

    深入理解C++中五种强制类型转换的使用场景 1.C风格的强制类型转换 2.C++风格的强制类型转换 2.1.static_cast 2.1.1.用于基本内置数据类型之间的转换 2.1.2.用于指针之间 ...

  5. C++中的向上类型转换和向下类型转换+四种强制类型转换

    转自博客:http://blog.csdn.net/wangweitingaabbcc/article/details/7720979# 在c++的世界中有这样两个概念,向上类型转换,向下类型转换,分 ...

  6. C++中4种强制类型转换 ?

    C++中4种强制类型转换 前言 C风格的转换格式很简单,但是有不少缺点 C++中的类型转换: 一.static_cast转换 二.dynamic_cast转换 三.const_cast转换 四.rei ...

  7. C++的四种强制类型转换

    C++的四种强制类型转换,所以C++不是类型安全的.分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast 为什么使用C风格的强制 ...

  8. linux 强制类型转换,C++ 新标准下的强制类型转换详解

    使用标准C++的类型转换符:static_cast.dynamic_cast.reinterpret_cast和const_cast. static_cast 用法:static_cast (expr ...

  9. c语言const类型强制转换,关于C++的强制类型转换浅析

    前言 一说起强制类型转换大家都很熟悉,相信很多学习完C++的朋友还在使用C语言的强制类型的方式 (类型)变量. C++其实也具有自己的一套强制类型转换它们分明是:static_cast  reinte ...

最新文章

  1. 定义自己的rm command
  2. CSS里常见的块级元素和行内元素
  3. QT 建立信号和槽的联系(事件处理)
  4. 【Uva 1625】Color Length
  5. 什么数据库比mysql效率高_牛x!一款比传统数据库快 100-1000 倍的数据库,来认识一下?...
  6. 外挂学习之路(11)--- 背包数据的遍历
  7. java是解释型编程语言_程序设计语言可以分为两类:编译型语言和解释型语言...
  8. 关于水晶报表出现登录窗口问题的解决方法
  9. java test20006_java 数组 (数组个数小于2000)
  10. nmd测试软件中文,阿迪达斯Boost传说中的踩屎感,NMD跑步真假对比测评!
  11. java 分布式任务_Java中实现分布式定时任务
  12. antd表格分页设置
  13. 面对“职业规划”问题,程序员应该如何回答?
  14. linux安装程序时Cannot uninstall XXX. It is a distutils installed project and thus we cannot accurately
  15. 如何成功对接APP项目资源
  16. 【verilog】按键消抖(FPGA,低电平有效按键,状态机法)
  17. 遗传算法的理解及例子解释
  18. oracle FAQ
  19. 动态规划法——常见题型及算法思路
  20. dump在计算机中的意义

热门文章

  1. 题目1470:调整方阵
  2. linux基础2-cd、mkdir、touch、umask、chattr、lsattr、SUID/SGID/Sticky Bit
  3. SpringBoot jar包不支持jsp
  4. 个性化推荐系统(一)---今日头条等的内容划分、分类
  5. Java新手问题 02 面向对象基本功
  6. python - 面向对象(二)
  7. 笔记:Hadoop权威指南 第4章 Hadoop I/O
  8. jQuery Masonry 一个 jQuery动态网格布局的插件
  9. 中国大陆穷光蛋排行榜---转
  10. virtualbox虚拟机XP连接本地WinXP