C 为什么非要引入那几种类型转换?

  1. 为什么要引入这几种类型转换,它与C语言中的强制类型转换有什么区别?

  2. 这四种类型转换分别应用在什么场景?

C 为什么要引入这几种强制类型转换?

我们都知道C 完全兼容C语言,C语言的转换方式很简单,可以在任意类型之间转换,但这也恰恰是缺点,因为极其不安全,可能不经意间将指向const对象的指针转换成非const对象的指针,可能将基类对象指针转成了派生类对象的指针,这种转换很容易出bug,需要严格审查代码才能消除这种隐患,但是C这种转换方式不利于我们审查代码,且程序运行时也可能会出bug。

而C 引入的这几种类型转换可以完美的解决上述问题,不同场景下不同需求使用不同的类型转换方式,同时有利于代码审查。

下面详细介绍这四种类型转换的使用场景:

static_cast

使用方式:

#include
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;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;}

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

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

dynamic_cast

使用方式:

#include
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(b);    dd->Func();    return 0;}

使用场景:用于将父类的指针或引用转换为子类的指针或引用,此场景下父类必须要有虚函数,因为dynamic_cast是运行时检查,检查需要运行时信息RTTI,而RTTI存储在虚函数表中。

const_cast

使用方式:

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;}

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

reinterpret_cast

使用方式:

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

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

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言笔试两题,有坑

题目一最近遇到的一个华为笔试题题目&#xff1a;对字符串中的所有单词进行倒排。说明&#xff1a;1、构成单词的字符只有26个大写或小写英文字母&#xff1b;2、非构成单词的字符均视为单词间隔符&#xff1b;3、要求倒排后的单词间隔符以一个空格表示&#xff1b;如果原字符串…

嵌入式linux文件系统启动,嵌入式Linux之文件系统启动分析【原创】

this.p{ m:2,b:2,loftPermalink:,id:fks_094068082086089066084084095095080087080066082082083075,blogTitle:嵌入式Linux之文件系统启动分析【原创】,blogAbstract:author&#xff1a;张继飞写在前面&#xff0c;这一切必须是在Linux内核挂载文件系统后。在Linux内核中找到/i…

C语言:如何定义一个和库函数名一样的函数,并在函数中调用该库函数

某个函数fun_1()是在lib内&#xff0c;没法修改的&#xff0c;在程序中大量的使用了该函数&#xff0c;现在想把原本fun_1失效&#xff08;现在失效的方法是#define fun_1(..)),用另外一个函数fun_2(),可是fun_2最后也需要调用fun_1,上面的失效方法感觉就不行了&#xff0c;请问…

C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它!

看山是山&#xff0c;看山不是山&#xff0c;最终看山才是山&#xff0c;并且是无穷的山峦。当我们学习一门技术的时候&#xff0c;起初是先模仿&#xff0c;但是最终是为了超越&#xff0c;也就是得到秘籍&#xff0c;看到本质。于是&#xff0c;今天来继续看可变参数&#xf…

java8升级java12_为什么现在是升级到Java 8的最佳时机

java8升级java12有兴趣了解如何通过AppDynamics充分利用Java 8的新功能吗&#xff1f; 立即开始免费试用 &#xff01; 今年3月&#xff0c;Oracle发布了近十年来最受期待的版本Java8。自发布以来&#xff0c;最新版本引起了越来越多的关注&#xff0c;各种规模的公司都渴望升…

C语言#include还有些你不知道的事

#include简介在C语言中#include是preprocessor的一条指令&#xff0c;告诉预处理器将指定头文件的内容插入到预处理器命令的相应位置。#include "xxx.h" 和 #include有两种方式可以指定插入头文件&#xff1a;#include #include "filename"如果需要包含标…

java常见的ide_在三个Java IDE中生成的三种常见方法

java常见的ide在本文中&#xff0c;我研究了NetBeans 8.0.2 &#xff0c; IntelliJ IDEA 14.0.2和Eclipse Luna 4.4.1生成的三种“通用”方法[ equals&#xff08;Object&#xff09; &#xff0c; hashCode&#xff08;&#xff09;和toString&#xff08;&#xff09; ]的区别…

深度linux安装依赖,Linux -- Ubuntu下载deepin wine依赖问题笔记

问题开始下载deepin-wine安装包, 请稍后…1.1udis86_1.72-2_i3 100%[>] 34.18K 87.3KB/s 用时 0.4s1.2deepin-fonts-win 15%[> ] 31.18K 1.72KB/s 用时 18s1.2deepin-fonts-win 100%[>] 207.88K 26.2KB/s 用时 6.7s2.1deepin-libwine_2 100%[>] 18.97M 132KB/s 用时…

什么是C语言中的隐式函数声明?

「1、什么是C语言的隐式函数声明」在C语言中&#xff0c;函数在调用前不一定非要声明。如果没有声明&#xff0c;那么编译器会自动按照一种隐式声明的规则&#xff0c;为调用函数的C代码产生汇编代码。下面是一个例子&#xff1a;int main(int argc, char** argv) {double x a…

群晖 上传 源文件不存在_群晖NAS连接百度网盘报错?原因是这样的

群晖NAS附带的云同步套件可以与国内外多个网盘连接 , 连接后可从云上下载数据亦可从本地将数据上传到云上。例如通过云同步套件连接百度网盘账号后可以便捷上传和下载数据 , 若网盘空间较大甚至可用来备份整个NAS等。不过现在看来群晖与百度网盘的合作似乎已经结束&#xff0c;…

ssl/tls服务器瞬时_SSL / TLS REST服务器–带有Spring和TomEE的客户端

ssl/tls服务器瞬时在构建系统时&#xff0c;开发人员通常会忽略安全性方面。 安全一直是令人担忧的重要问题&#xff0c;但是它比以前吸引了更高的关注。 就在今年&#xff0c;我们发生了像Heartbleed Bug或CelebrityGate丑闻这样的案件。 这与帖子无关&#xff0c;只是安全真正…

linux kvm百度云,容器与云|如何在 Ubuntu Linux 上使用 KVM 云镜像

如何下载并使用运行在 Ubuntu Linux 服务器上的 KVM 云镜像&#xff1f;如何在 Ubuntu Linux 16.04 LTS 服务器上无需完整安装即可创建虚拟机&#xff1f;如何在 Ubuntu Linux 上使用 KVM 云镜像&#xff1f;基于内核的虚拟机(KVM)是 Linux 内核的虚拟化模块&#xff0c;可将其…

C 的16个大坑,你能躲过几个?

首先说下C 和C语言有什么区别&#xff1f;分享一个我在知乎上看见的回答&#xff1a;C ≈ C with classes&#xff0c; C with STLC&#xff1a;面向机器编程C &#xff1a;面向编译器编程C 有个很重要的特性叫RAII&#xff0c;个人认为可以多多使用&#xff0c;相当方便。言归…

java 性能调优_Java性能调优调查结果(第三部分)

java 性能调优这是本系列文章的第三篇&#xff0c;我们将分析2014年10月进行的调查的结果。如果您尚未这样做&#xff0c;我建议从本系列的前两篇文章开始&#xff1a; 问题严重性分析和监视域分析 。 这篇文章着重于故障排除/根本原因检测。 本调查部分的背景&#xff1a;意识…

不懂指针类型,7个例子给你讲明白

1. int va;这是一个整型变量&#xff0c;32位CPU的话&#xff0c;占有32个bite2. int *va;这是一个整型指针变量&#xff0c;用于存放一个整型变量的地址&#xff0c;3. int **va;这是一个整型的二级指针&#xff0c;用于存放一个内存的地址&#xff0c;该地址对应的内存中存放…

Tomcat与Netty比较

Tomcat介绍Tomcat支持的协议Tomcat的优缺点Netty介绍Netty支持的协议Netty的优点和缺点Tomcat和Netty的区别Tomcat和Netty的应用场Tomcat和Netty来处理大规模并发连接的优化Tomcat与Netty的网络模型的区别Tomcat与Netty架构设计拓展 Tomcat介绍 Tomcat是一个免费的、开放源代码…

C或C 如何通过程序执行shell命令并获取命令执行结果?

1 应用场景最近在实际程序开发中&#xff0c;需要通过程序执行 shell 命令&#xff0c;并获取命令输出内容。但是系统自带的 system 只能返回命令执行成功与否&#xff0c;不能捕获命令输出。2 扩展性由于应用场景本就广泛&#xff0c;因此扩展性较好。此函数可以执行任意命令&…

linux centos7安装ngix,centos7 环境下安装nginx--Linux

本文将要为您介绍的是centos7 环境下安装nginx--Linux,具体完成步骤:一、安装前需要的编译环境准备1、安装makeyum install -y gcc automake autoconf libtool make2、安装gcc、gcc-cyum install -y gcc gcc-c3、关闭防火墙iptables -F4、关闭selinux#临时关闭&#xff1a;sete…

primefaces_使用PrimeFaces开发数据导出实用程序

primefaces我的日常工作涉及大量使用数据。 我们使用关系数据库来存储所有内容&#xff0c;因为我们依赖于企业级的数据管理。 有时&#xff0c;具有将数据提取为简单格式&#xff08;例如电子表格&#xff09;的功能很有用&#xff0c;以便我们可以按需进行操作。 这篇文章概述…

如何优雅地实现判断一个值是否在一个集合中?

如何判断某变量是否在某个集合中&#xff1f;注意&#xff0c;这里的集合可能并不是指确定的常量&#xff0c;也可能是变量。版本0#include int main(){int a 5;if(a 1 || a 2 || a 3 || a 4 || a 5){std::cout<<"find it"<<std::endl;}return 0;…