作者:李春港

出处:https://www.cnblogs.com/lcgbk/p/14209848.html

一、前言

在C语言中,我们经常会对数据进行类型转换,但都是强制性的类型装换,自然就会引发访问不安全的问题,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,而且这种转换方式不利于我们审查代码,且程序运行时也可能会出bug,所以C++为了提高类型装换的安全性,关于类型转换引入了四种方式:static_cast、const_cast、dynamic_cast、reinterpret_cast,接下来看下其四种类型装换的应用场景。

二、static_cast

2.1 使用场景

基本数据类型之间的转换使用,例如float转int,int转char等,在有类型指针和void*之间转换使用,子类对象指针转换成父类对象指针也可以使用static_cast。

非多态类型转换一般都使用static_cast,而且最好把所有的隐式类型转换都是用static_cast进行显示替换,不能使用static_cast在有类型指针之间进行类型转换。

2.2 实例

#include <iostream>

using namespace std;

struct Base {
virtual void Func() { cout << "Base Func \n"; }
}; struct Derive : public Base {
void Func() override { cout << "Derive Func \n"; }
}; int main()
{
float f = 1.23;
cout << "f " << f << endl;
int i = static_cast<int>(f);
cout << "i " << i << endl; void *p;
int *i_p = static_cast<int *>(p);
void *pi = static_cast<void *>(&f);
int *pi = static_cast<int *>(&f); // error invalid static_cast from type ‘float*’ to type ‘int*’ Derive d;
d.Func();
Base *b = static_cast<Base *>(&d);
b->Func();
return 0;
}

三、dynamic_cast

3.1 使用场景

用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行),因为dynamic_cast是运行时检查,检查需要运行时信息RTTI.如果不清楚什么是RTTI,可以去了解下C++的RTTI机制。

3.2 实例

#include <iostream>

using namespace std;

struct Base {
virtual void Func() { cout << "Base Func \n"; }
}; struct Derive : public Base {
void Func() override { cout << "Derive Func \n"; }
}; int main() {
Derive d;
d.Func();
Base *b = dynamic_cast<Base *>(&d);
b->Func();
Derive *dd = dynamic_cast<Derive *>(b);
dd->Func();
return 0;
}

四、const_cast

4.1 使用场景

用于常量指针或引用与非常量指针或引用之间的转换,只有const_cast才可以对常量进行操作,一般都是用它来去除常量性,去除常量性是危险操作,还是要谨慎操作。

4.2 实例

int main() {
int data = 10;
const int *cpi = &data; int *pi = const_cast<int *>(cpi); const int *cpii = const_cast<const int *>(pi);
return 0;
}

五、reinterpret_cast

5.1 使用场景

没啥场景,类似C语言中的强制类型转换,什么都可以转,万不得已不要使用,一般前三种转换方式不能解决问题了使用这种强制类型转换方式。

5.2 实例

int main() {
int data = 10;
int *pi = &data; float *fpi = reinterpret_cast<float *>(pi); return 0;
}

六、总结

方式 使用场景
static_cast 基本数据类型之间的转换使用,例如float转int,int转char等;子类对象指针转换成父类对象指针也可以使用static_cast;在有类型指针和void*之间转换使用,不能使用static_cast在有类型指针之间进行类型转换。
dynamic_cast 用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数(只要拥有虚函数就行)
const_cast 用于常量指针或引用与非常量指针或引用之间的转换。
reinterpret_cast 类似C语言中的强制类型转换,什么都可以转,尽量不要使用此方式。

【C++】C++之类型转换的更多相关文章

  1. 为C# as 类型转换及Assembly.LoadFrom埋坑!

    背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...

  2. c# 基础 object ,new操作符,类型转换

    参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...

  3. Struts2日期类型转换

    针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...

  4. 【.NET深呼吸】基础:自定义类型转换

    照例,老周在开始吹牛之前,先讲讲小故事,这是朋友提出的建议,老TMD写技术有什么了不起的,人人都会写.后来老周想想,也确实,代码谁不会写,能写到有品位有感悟,就不容易做到.于是,老周接受了该朋友的建议 ...

  5. C++四种类型转换方式。

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  6. struts2类型转换

    1. Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概念除了用 ...

  7. C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》

    上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...

  8. Struts2入门(三)——数据类型转换

    一.前言 笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解.好了,不说废话. 1.1.类型转换为何存在?什么是类型转换? 在MVC框架中,都是属于表示层解决方案,都需 ...

  9. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  10. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

随机推荐

  1. KNN 算法-理论篇-如何给电影进行分类

    公号:码农充电站pro 主页:https://codeshellme.github.io KNN 算法的全称是K-Nearest Neighbor,中文为K 近邻算法,它是基于距离的一种算法,简单有效 ...

  2. LeetCode 046 Permutations

    题目要求:Permutations(全排列) Given a collection of numbers, return all possible permutations. For example, ...

  3. gulp常用配置

    由于项目中经常会使用到gulp,而每次配置大概都差不多,所以将配置记录一下 项目结构 ├─dist │ ├─assets │ ├─css │ ├─images │ └─js ├─node_module ...

  4. rest-framework 分页器

    一 简单分页(查看第n页,每页显示n条) from rest_framework.pagination import PageNumberPagination # 一 基本使用:url=url=htt ...

  5. Django----View.py

    ·首先先下载安装包· pip install djangorestframework==3.11.1 pip install django-filter==2.3.0 # 过滤器 pip instal ...

  6. JZOJ 11.28 提高B组反思

    JZOJ 11.28 提高B组反思 被打崩了呀 下次打提高A去了(逃 T1 刚开始没有读懂题,后来读懂了以后没有思路.没有想到是一个构造题,对同构的性质没有了解清楚,题解也讲的不明不白,懵-- T2 ...

  7. Spring Boot + MongoDB 使用示例

    本文分别使用 MongoRepository 和 MongoTemplate 实现 MongoDB 的简单的增删改查 本文使用 docker 安装 MongoDB: 使用示例 application. ...

  8. intelliJ IDEA 鼠标光标消失问题

    经常会遇到,光标就莫名消失了,得重启 IntelliJ IDEA 才行,到官方论坛询问才得知,系统时间如果被调前就会发生这个情况,我想原因是之前的破解是用的调系统时间的方式,所以留下了这个bug,总之 ...

  9. Python中的"缝合器"zip函数:将多个可迭代对象组合成一个迭代器

    zip函数将参数中多个可迭代对象中相同序号的元素取出组合成一个元组作为输出列表的一个同样序号的元素,即输出列表的每个元素是一个元组,该元组的元素来源于参数中每个迭代对象的对应序号的元素. 具体可参考: ...

  10. PyQt(Python+Qt)学习随笔:QTableWidgetItem项数据的data和setData访问方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget部件中的QTableWidgetItem项数据可以通过项的data( int ...