作者:李春港

出处: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. LeetCode 026 Remove Duplicates from Sorted Array

    题目描述:Remove Duplicates from Sorted Array Given a sorted array, remove the duplicates in place such t ...

  2. 下载centos镜像的地址

  3. IdentityServer4系列 | 快速搭建简易项目

    一 .前言 从上一篇关于 常见术语说明中,主要是对IdentityServer4的说明,以及其中涉及常见的术语的表述说明,包括对身份认证服务器.用户.客户端.资源以及各个令牌等进行对比区别说明. 而在 ...

  4. 2017 Mid Central Regional G.Hopscotch (组合计数)

    这道题有点意思,给出点(N,N),你在原点处向目标点走,每次只能向x和y两个方向走路,每次xy两个方向的步幅分别不能小于dx和dy,问走到终点的方案数,答案对1e9 + 7取模 这道题最直接的想法就是 ...

  5. 基于vue(element ui) + ssm + shiro 的权限框架

    zhcc 基于vue(element ui) + ssm + shiro 的权限框架 引言 心声 现在的Java世界,各种资源很丰富,不得不说,从分布式,服务化,orm,再到前端控制,权限等等玲琅满目 ...

  6. PyQt(Python+Qt)学习随笔:Qt Designer中部件的mouseTracking和tabletTracking属性

    在Qt Designer中的部件属性设置中,有mouseTracking和tabletTracking两个属性,这两个属性是跟踪鼠标或平板触控笔的移动轨迹的. 一.mouseTracking mous ...

  7. 优化 Webpack 的构建速度

    1.使用高版本的 Webpack 和 Node.js 2.多进程/多实例构建:HappyPack(不维护了).thread-loader 3.压缩代码 webpack-paralle-uglify-p ...

  8. 【SPOJ QTREE4】Query on a tree IV(树链剖分)

    Description 给出一棵边带权(\(c\))的节点数量为 \(n\) 的树,初始树上所有节点都是白色.有两种操作: C x,改变节点 \(x\) 的颜色,即白变黑,黑变白. A,询问树中最远的 ...

  9. MySQL技术内幕InnoDB存储引擎(五)——索引及其相关算法

    索引概述 索引太多可能会降低运行性能,太少就会影响查询性能. 最开始就要在需要的地方添加索引. 常见的索引: B+树索引 全文索引 哈希索引 B+树索引 B+树 所有的叶子节点存放完整的数据,非叶子节 ...

  10. nginx: [emerg] bind() to 0.0.0.0:80 failed (48: Address already in use)

    Mac上启动nginx报如上错误,原因是80端口已被占用,可能有些服务未能成功关闭. 解决:键入命令 sudo nginx -s stop ( 或 sudo nginx -s  quit) ,然后 s ...