1. static_cast

实现C++种内置基本数据类型之间的相互转换,不能用于两个不相关类型进行转换。

例如:将整形数据转换为浮点型

  1. c语言方式
int a = 8;
int b = 3;
double result = (double)a / (double)b;
  • 1
  • 2
  • 3
  1. C++方式
int a = 8;
int b = 3;
double result = static_cast<double>(a) / static_cast<double>(b);
  • 1
  • 2
  • 3

格式如下:

static_cast<类型>(变量表达式)

应用场景:

  • 用于类层次结构中基类和派生类之间引用或指针的转换。
    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的。
    进行下行转换(把基类的指针或引用转换成派生类表示),由于没有动态类型检查,不安全。
  • 用于基本数据类型之间的转换
  • 把空指针转换成目标类型的空指针
  • 把任何类型的表达式转换成void类型

2. dynamic_cast

用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)。

dynamic_cast< type_id >(expression)

  • type_id 必须是类的指针、类的引用或者void*。
  • 主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
  • dynamic_cast只能用于含有虚函数的类;
  • 进行上行转换的时候,与static_cast 的作用一样。下行转换的时候,具有类型检查的功能,比static_cast更安全。
  • dynamic_cast会先检查是否能转换成功,如果能则转换,不能则返回0。
class B
{
public:
int m_iNum;
virtual void foo();
}; class D : public B
{
public:
char *m_szName[100];
}; void func(B *pb)
{
D *pd1 = static_cast(pb);
D *pd2 = dynamic_cast(pb);
}
  • 1
  • 2

如果pb指向一个D类型的对象,pd1 和 pd2 是一样的,并且这两个指针执行D类型的任何操作都是安全的。

如果指向B的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作是不安全的。pd2将是一个空指针。

B要有虚函数:

这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。

3. const_cast

c语言中,const是用来限定变量,表示该变量的值不能更改。

const_cast 是用来强制去掉这种不能被修改的常数特性。不是去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,对象必须为指针或引用。

const_cast<type_id>(expression)

用来修改类型的const或volatile属性。

常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。

include<iostream>
using namespace std; int main()
{
const int a = 10;
const int * p = &a;
int *q;
q = const_cast<int *>(p);
*q = 20; //fine
cout <<a<<" "<<*p<<" "<<*q<<endl;
cout <<&a<<" "<<p<<" "<<q<<endl;
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

定义了一个普通指针q。将p通过const_cast去掉其常量性,并赋值给q指针。

4. reinterpret_cast

通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。

reinterpret_cast<type_id>(expression)

type_id 必须是一个指针、引用、算术类型、函数指针、成员指针。

应用场景:

改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整形转换为指针或引用。

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

5. 为什么要需要四种类型转换?

C风格的转换格式很简单,但是也有缺点:

  • 过于粗暴,可以在任意类型之间转换,很难判断其正确性。
  • 隐式转换有些情况会出问题:比如精度丢失。
  • 显示转换和隐式转换混合在一起,很难快速定位全部的强制转换语句。

但是在实际的工程中强制转换是不可避免的,为此C++提供的四种强制类型转换提供了更加安全可靠的转换。

【C++】 四种强制类型转换(static_cast 与 dynamic_cast 的区别!)的更多相关文章

  1. 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...

  2. C++中的关键字用法--- 四种强制类型转换的总结

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast 1. C风格的强制类型转换(Type Cast)很简单,不管什么类 ...

  3. [转载]C++中四种强制类型转换方式

    C++中四种强制类型转换方式 原文地址:http://www.cnblogs.com/home123/p/6763967.html 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单( ...

  4. C++中的四种强制类型转换符详解

    阅读目录 C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非con ...

  5. C++四种强制类型转换详解

    什么是类型转换? 类型转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式.为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符. C与C++的类型转换 //C中: //复 ...

  6. C++中四种强制类型转换区别详解

    C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 1.转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非const对 ...

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

    来自csdn:http://blog.csdn.net/hgl868/article/details/46619399 C风格的强制类转换(Type Cast)很简单,不管什么类型的转换统统是: TY ...

  8. C++开发必看 四种强制类型转换的总结 [转]

    一.C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:     TYPE b = (TYPE)a 二.C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用. co ...

  9. C++四种强制类型转换关键字

    C语言使用强制类型转换(Type Cast)很简单,不管什么类型的转换,形式都如下: TYPE b = (TYPE)a; c++提供了4种类型转换操作符来应对不同场合的应用. const_cast   ...

随机推荐

  1. AcWing 1086. 恨7不成妻(【代码简洁】标准记忆化搜索+超详解!!)

    看到这题用循环写的dp代码瑟瑟发抖~ 数位dp一般记忆化搜索的写法思维难度较低,也比较常用,这题的简洁代码应该就可以显现出其优越性 (用时4ms,可能比用循环写的dp还要快) 那这里补充一下记忆化搜索 ...

  2. 实验 1 Linux 系统的安装和常用命令

    实验 1 Linux 系统的安装和常用命令 (题目) 一.实验目的 (1)掌握 Linux 虚拟机的安装方法.Spark 和 Hadoop 等大数据软件在 Linux 操作系统 上运行可以发挥最佳性能 ...

  3. [刘阳Java]_Spring AOP基于XML配置介绍_第9讲

    基于注解配置的Spring AOP固然简单,但是这节我们会给大家介绍基于XML配置的AOP是如何应用的.为什么这么说了,因为后面我们还会介绍到Spring对Dao操作的事务管理(基于AOP的XML文件 ...

  4. 传统.NET 4.x应用容器化体验(4)

    上一篇我们试着将.NET 4.x的镜像推送到harbor私有镜像仓库,本篇我们来使用一下阿里云的镜像仓库服务并了解一下携程的实践. 1 关于阿里云镜像仓库 阿里云容器镜像服务(简称 ACR)是面向容器 ...

  5. kubespray-2.14.2安装kubernetes-1.18.10(ubuntu-20.04.1)

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. vue(21)初识Vuex

    Vuex是做什么的? 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex ...

  7. Windows内核开发-4-内核编程基础

    Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...

  8. ssm框架下 数据库连接异常 java.sql.SQLException: The server time zone value '???&#250;&#177;&#234;&#215;??&#177;??' is unrecognized or represents more

    1.错误截图 2.修改操作 我是在框架的中连接的数据库,如果在类中把    &换成& 修改前代码 <property value="com.mysql.jdbc.Dri ...

  9. 13Java进阶——IO、线程

    1 字节缓冲流 BufferInputStream 将创建一个内部的缓冲区数组,内部缓冲区数组将根据需要从包含的输入流中重新填充,一次可以读取多个字节 BufferOutputStream 该类实现缓 ...

  10. JavaScript之DOM、DOM树

    一 DOM JavaScript操作网页的接口,全称为"文档对象模型"(Document Object Model). 有这几个概念:文档.元素.节点 整个文档是一个文档节点 每个 ...