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,一经查实,立即删除!

相关文章

删除一个程序Linux,一天一个Linux基础命令删除文件或目录命令rm

rm删除文件命令1、命令格式rm [options] file...2、命令功能rm命令&#xff0c;删除文件命令&#xff0c;是Linux系统下常用命令&#xff0c;该命令的功能为删除一个文件或者整个目录或者目录中的部分文件&#xff0c;它也可以将某个目录及其下的所有文件及子目录均删除。对于…

C语言笔试两题,有坑

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

python apply_async函数_进程池未执行apply_async中添加的函数就直接结束了

代码没有执行apply_async中添加的函数就直接结束了from bs4 import BeautifulSoupimport randomimport requestsimport pymongoimport datetimeimport randomimport timefrom multiprocessing import Pooluser_agents [Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X)…

java8 streams_Java 8 Streams API作为友好的ForkJoinPool外观

java8 streams我最喜欢Java 8的功能之一是流API。 最终&#xff0c;它消除了代码中的几乎所有循环&#xff0c;并使您可以编写更具表现力和重点的代码。 今天&#xff0c;我意识到它可以用于其他用途&#xff1a;作为ForkJoinPool一个不错的前端。 问题&#xff1a;执行器样板…

嵌入式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;请问…

python计算派的近似值、当任意项的值小于10^-4_编程计算e的近似值,直到最后一项的绝对值小于10^-5时为止,输出e的值并统计累加项数...

展开全部1、问62616964757a686964616fe4b893e5b19e31333433633530题主要是类型的问题。因为a 是int型的&#xff0c;在计算的时候不转型成浮点型是不对的(1/a0)因此要写成&#xff1a;pipi1.0/(2*a-1);pipi-1.0/(2*a-1);还有判断条件&#xff1a;while ((1.0/a)>1e-4);另外&…

jdk8集合类流_JDK 8中的流驱动的集合功能

jdk8集合类流这篇文章介绍了JDK 8的应用–引入了带有集合的 流 &#xff0c;以更简洁地完成通常需要的与集合相关的功能。 在此过程中&#xff0c;将演示并简要说明使用Java Streams的几个关键方面。 请注意&#xff0c;尽管JDK 8 Streams通过并行化支持提供了潜在的性能优势&a…

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

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

Linux下CMAKE编译jsoncpp,使用CMake引入jsoncpp

在jni的cpp中使用json&#xff0c;百度了一下&#xff0c;大多都是下面这个库&#xff0c;但是和之前的文档有点出入了&#xff0c;记录一下。jsoncpp库地址&#xff1a;添加jsoncpp库在cpp目录下创建一个jsoncpp目录下载jsoncpp项目把src\lib_json文件夹下的文件都拉到项目的c…

python打印星星居中_python实现while循环打印星星的四种形状

在控制台连续输出五行*,每一行星号数量一次递增***************#1.定义一个行计数器row 1while row < 5:#定义一个列计数器col 1#开始循环while col < row:print(*,end)col 1print()row 1如果想要星星倒过来呢#1.定义一个行计数器row 1while row < 5:#定义一个列…

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;相当方便。言归…