【C++】C++之类型转换
作者:李春港
出处: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++之类型转换的更多相关文章
- 为C# as 类型转换及Assembly.LoadFrom埋坑!
背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...
- c# 基础 object ,new操作符,类型转换
参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...
- Struts2日期类型转换
针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...
- 【.NET深呼吸】基础:自定义类型转换
照例,老周在开始吹牛之前,先讲讲小故事,这是朋友提出的建议,老TMD写技术有什么了不起的,人人都会写.后来老周想想,也确实,代码谁不会写,能写到有品位有感悟,就不容易做到.于是,老周接受了该朋友的建议 ...
- C++四种类型转换方式。
类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...
- struts2类型转换
1. Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概念除了用 ...
- C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》
上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...
- Struts2入门(三)——数据类型转换
一.前言 笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解.好了,不说废话. 1.1.类型转换为何存在?什么是类型转换? 在MVC框架中,都是属于表示层解决方案,都需 ...
- js条件判断时隐式类型转换
Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...
- JavaScript中数据类型转换总结
JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...
随机推荐
- c++11-17 模板核心知识(十一)—— 编写泛型库需要的基本技术
Callables 函数对象 Function Objects 处理成员函数及额外的参数 std::invoke<>() 统一包装 泛型库的其他基本技术 Type Traits std:: ...
- 20200315_python3.6去除标点符号
line = "python3.6下进行去!@#$%^&*()除标点测试,:!大家好,:!&>啥都不是!@#¥%--&*(-.||" # python ...
- flask基本使用
一.flask安装以及启动 1.安装 pip install flask 2.开启第一个flask项目 新建文件HelloWord.py from flask import Flask app = F ...
- 使用PyQt进行Python图形界面程序开发文章目录
☞ ░ 前往老猿Python博文目录 ░ PyQt入门知识原来是作为老猿Python<Python基础教程目录>后的进阶学习章节存在,最近不少专栏作者提醒老猿整体的博文内容不错,但博文没有 ...
- Python文件操作函数os.open、io.open、内置函数open之间的关系
Python提供了多种文件操作方式,这里简单介绍os.open.io.open.内置函数open之间的关系: 一.内置函数open和io.open实际上是同一个函数,后者是前者的别名: 二.os.op ...
- 性能测试学习之路 (三)jmeter常见性能指标(相关术语、聚合报告 && 服务器性能监控配置 && 图形结果 && 概要报告)
1 性能测试目的 性能测试的目的:验证软件系统是否能够达到用户提出的性能指标,同时发现软件系统中存在的性能瓶颈,以优化软件. 最后起到优化系统的目的性能测试包括如下几个方面: 1.评估系统的能力:测试 ...
- centos 6.4-linux环境配置,安装hadoop-1.1.2(hadoop伪分布环境配置)
1 Hadoop环境搭建 hadoop 的6个核心配置文件的作用: core-site.xml:核心配置文件,主要定义了我们文件访问的格式hdfs://. hadoop-env.sh:主要配置我们的j ...
- AcWing 311 .月之谜
大型补档补了一年 题目链接 考虑枚举月之数的数列和,然后展开dp预处理 设当前模数为 \(P\) \(f[i][j][k]\) 表示一共有 i 位数字,数位和为 j,数值和 % P 的值为 K \(f ...
- Windows的API功能查询
在逆向分析时,一些Windows的API函数往往是我们的突破口.但这些函数很难记得一清二楚,以下是我的查找办法,做个小结. 官网 https://docs.microsoft.com/en-us/wi ...
- tomcat-1-介绍篇
java语言分为三个体系: javase javaee,是javase的基础 一般就是指jdk javaee java的企业版本 其实是一套规范,就是用java语言做企业开发(目前看来就是开发一些动态 ...