【C++高阶(九)】C++类型转换以及IO流

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C++从入门到精通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习C++
  🔝🔝


在这里插入图片描述

C++高阶

  • 1. 前言
  • 2. C语言类型转换的方式
  • 3. C++的强制类型转换
  • 4. RTTI介绍(了解)
  • 5. C语言的输入输出和缓冲区
  • 6. C++IO流
  • 7. C++文件IO流
  • 8. 总结以及拓展

1. 前言

C语言中常见的类型转换有隐式类型
转换和强制转换,但是在面向对象的
语言中,这样使用未免太不优雅了!

本章重点:

本篇文章前半截着重讲解C++强制
转换的四种类型,以及为什么C++
需要自己设计一套类型转换.其中
会复习C语言的类型转换的方式.
后半截会讲解C++的IO流和文件IO
还会介绍string stream相关知识


2. C语言类型转换的方式

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
int i = 1;
// 隐式类型转换
double d = i;
printf("%d, %.2f\n" , i, d);
  1. 显式类型转化:需要用户自己处理
int* p = &i;
// 显示的强制类型转换
int address = (int) p;
printf("%x, %d\n" , p, address);

C语言类型转换的缺陷:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰

因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。


3. C++的强制类型转换

标准C++为了加强类型转换的可视性
引入了四种命名的强制类型转换操作符:

static_castreinterpret_castconst_castdynamic_cast

下面将一一介绍它们的用法:

  1. static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换

double d = 12.34;
int a = static_cast<int>(d);//将d强制转换为int类型
cout<< a <<endl;
  1. reinterpret_cast

reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型

double d = 12.34;
int a = static_cast<int>(d);
cout << a << endl;
// 这里使用static_cast会报错,应该使用reinterpret_cast
//int *p = static_cast<int*>(a);
int *p = reinterpret_cast<int*>(a);
  1. const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值

const int a = 2;
int* p = const_cast<int*>(&a);
*p = 3;
cout << a << endl;
cout << *p << endl;

请注意,当你去测试这段代码时,确实不会报错,但是打印出来a的结果是2而不是3,*p的结果是3,这是因为当a被赋予const属性后,操作系统内部会做优化,每次使用a时会直接去寄存器中取,而不是去内存中取,显然,内存中的a已经被修改了!

在这里插入图片描述

  1. dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用

  • 向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
  • 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

注意:

  1. dynamic_cast只能用于父类含有虚函数的类
  2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0
class A
{
public :virtual void f(){}
};
class B : public A
{};void fun (A* pa)
{// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回B* pb1 = static_cast<B*>(pa);B* pb2 = dynamic_cast<B*>(pa);cout<<"pb1:" <<pb1<< endl;cout<<"pb2:" <<pb2<< endl;
}
int main ()
{A a;B b;fun(&a);fun(&b);return 0;
}

用dynamic_cast转换只是安全的
并不代表一定能转换成功!


4. RTTI介绍(了解)

RTTI:Run-time Type identification
即:运行时类型识别

C++通过以下方式来支持RTTI:
1. typeid运算符
2. dynamic_cast运算符
3. decltype

这三种方式我们都学过了,RTTI
属于了解内容


5. C语言的输入输出和缓冲区

C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中。printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。注意宽度输出和精度输出控制。C语言借助了相应的缓冲区来进行输入与输出。如下图所示:

在这里插入图片描述

由于输入输出缓冲区是Linux系统
要学习的内容,所以这里就简单讲解

对输入输出缓冲区的理解:

  1. 可以屏蔽掉低级I/O的实现,低级I/O的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,可以很容易写出可移植的程序。
  2. 可以使用这部分的内容实现“行”读取的行为,对于计算机而言是没有“行”这个概念,只有文件满了才会刷新,缓冲区的存在可以让用户有更好的体验,也就是行刷新

6. C++IO流

C++系统实现了一个庞大的类库
其中ios为基类
其他类都是直接或间接派生自ios类
在这里插入图片描述

C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用cout进行标准输出,即数据从内存流向控制台(显示器)。使用cin进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同。

  1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。
  2. 输入的数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置位(置1),程序继续。
  3. 空格和回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入。
  4. cin和cout可以直接输入和输出内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了
  5. 对于自定义类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载。

7. C++文件IO流

C++根据文件内容的数据格式分为二进制文件和文本文件。采用文件流对象操作文件的一般步骤:

  1. 定义一个文件流对象
    ifstream ifile(只输入用)
    ofstream ofile(只输出用)
    fstream iofile(既输入又输出用)
  2. 使用文件流对象的成员函数打开一个磁盘文件,使得文件流对象和磁盘文件之间建立联系
  3. 使用提取和插入运算符对文件进行读写操作,或使用成员函数进行读写
  4. 关闭文件
struct ServerInfo
{char _address[32];int _port;Date _date;	
};
struct ConfigManager
{
public:
ConfigManager(const char* filename):_filename(filename)
{}
void WriteBin(const ServerInfo& info)
{ofstream ofs(_filename, ios_base::out | ios_base::binary);ofs.write((const char*)&info, sizeof(info));
}
void ReadBin(ServerInfo& info)
{ifstream ifs(_filename, ios_base::in | ios_base::binary);ifs.read((char*)&info, sizeof(info));
}// C++文件流的优势就是可以对内置类型和自定义类型,都使用// 一样的方式,去流插入和流提取数据// 当然这里自定义类型Date需要重载>> 和 <<// istream& operator >> (istream& in, Date& d)// ostream& operator << (ostream& out, const Date& d)
void WriteText(const ServerInfo& info)
{ofstream ofs(_filename);ofs << info._address << " " << info._port<< " "<<info._date;
}
void ReadText(ServerInfo& info)
{ifstream ifs(_filename);ifs >> info._address >> info._port>>info._date;
}
private:string _filename; // 配置文件
};
int main()
{ServerInfo winfo = { "192.0.0.1", 80, { 2022, 4, 10 } };// 二进制读写ConfigManager cf_bin("test.bin");cf_bin.WriteBin(winfo);ServerInfo rbinfo;cf_bin.ReadBin(rbinfo);cout << rbinfo._address << " " << rbinfo._port <<" "<<rbinfo._date << endl;// 文本读写ConfigManager cf_text("test.text");cf_text.WriteText(winfo);ServerInfo rtinfo;cf_text.ReadText(rtinfo);cout << rtinfo._address << " " << rtinfo._port << " " <<rtinfo._date << endl;return 0;
}

8. 总结以及拓展

本篇文章的内容不属于面试常考点,
但是了解了总比不了解号,没准面试官
问的偏,你这时就赢麻了(狗头)

拓展:

string stream的相关概念:

string stream介绍


🔎 下期预告:C++11线程库🔍

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

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

相关文章

什么是微服务架构以及落地思路

文章目录 前言一、各种架构的演进二、微服务架构落地思路 总结 前言 调用几个webapi就是微服务架构&#xff1f;或则是ngnixwebapi 集群就是微服务架构&#xff1f;这个文章带你弄懂微服务架构。 一、各种架构的演进 单体架构&#xff1a;放在一个服务器进程完成全部的后端处理…

Linux6.4、IO基础(整体深入理解文件描述符)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 本文章将从源码和内核剖析fd&#xff0c;细节和基础部分可以了解&#xff1a; 我们再来提起文件&#xff0c;文件可以分为两类&#xff1a; 磁盘文件 (未被打开)内存文件 (被进程在内存中打开) 同时我们也知道文件描…

logstash收集华为、H3C、Cisco交换机日志

网络设备配置 将 syslog-ip 替换成服务器的IP地址。 Huawei info-center loghost source interface info-center loghost syslog-ip local-time facility local6 H3C info-center loghost source interface info-center loghost syslog-ip facility local5 Aruba logging arm …

OAuth2授权码模式---详解

OAuth2简介 是一个业界标准的授权协议&#xff08;authorization protocol&#xff09;&#xff0c;这里的授权是以委派代理&#xff08;delegation&#xff09;的方式。可以这样理解&#xff0c;OAuth 2.0提供一种协议交互框架&#xff0c;让某个应用能够以安全地方式获取到用…

目标检测-Two Stage-SPP Net

文章目录 前言一、SPP Net 的网络结构和流程二、SPP的创新点总结 前言 SPP Net&#xff1a;Spatial Pyramid Pooling Net&#xff08;空间金字塔池化网络&#xff09; SPP-Net是出自何凯明教授于2015年发表在IEEE上的论文-《Spatial Pyramid Pooling in Deep ConvolutionalNetw…

模具图纸管理系统、模具图纸管理系统有哪些?

模具图纸管理系统是一种用于管理和跟踪模具图纸的软件系统。该系统可以帮助企业有效地组织、管理和分享模具图纸&#xff0c;从而提高生产效率、降低成本和减少错误。 以下是模具图纸管理系统的一些基本功能&#xff1a; 1、文件管理&#xff1a;将模具图纸存储在一个中心化的…

工具系列:PyCaret介绍_编写和训练自定义机器学习模型

文章目录 PyCaret安装PyCaret&#x1f449; 让我们开始吧&#x1f449; 数据集&#x1f449; 数据准备PyCaret中的设置函数&#x1f449; 可用模型&#x1f449; 模型训练与选择&#x1f449; 编写和训练自定义模型&#x1f449; GPLearn模型&#x1f449; NGBoost 模型&#x…

浅谈Redis分布式锁(下)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 自定义Redis分布式锁的…

SpringIOC之ApplicationContextAwareProcessor

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Java 将PDF 转为图片 工具 【Free Spire.PDF for Java】(免费版)

Java 将PDF 转为图片 使用工具&#xff1a;Free Spire.PDF for Java&#xff08;免费版&#xff09; Jar文件获取及导入&#xff1a; 方法1&#xff1a;通过官网下载jar文件包。下载后&#xff0c;解压文件&#xff0c;并将lib文件夹下的Spire.Pdf.jar文件导入Java程序。 方…

flex--伸缩性

1.flex-basis flex-basis 设置的是主轴方向的基准长度&#xff0c;会让宽度或高度失效。 备注&#xff1a;主轴横向&#xff1a;宽度失效&#xff1b;主轴纵向&#xff1a;高度失效 作用&#xff1a;浏览器根据这个属性设置的值&#xff0c;计算主轴上是否有多余空间&#x…

C语言操作符详情

C语言操作符详情 是否控制求值顺序中 只有“&&”“&#xff1f;&#xff01;”“&#xff0c;”“||”为“是” 其余均为“否”

模拟EXCEL排序

7-78 模拟EXCEL排序 分数 25 全屏浏览题目 作者 陈越 单位 浙江大学 Excel可以对一组纪录按任意指定列排序。现请编写程序实现类似功能。 输入格式: 输入的第一行包含两个正整数N(≤105) 和C&#xff0c;其中N是纪录的条数&#xff0c;C是指定排序的列号。之后有 N行&am…

Debezium发布历史30

原文地址&#xff1a; https://debezium.io/blog/2018/03/08/creating-ddd-aggregates-with-debezium-and-kafka-streams/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. 使用 Debezium 和 Kafka Streams 创建 …

Redis Streams在Spring Boot中的应用:构建可靠的消息队列解决方案【redis实战 二】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Redis Streams在Spring Boot中的应用&#xff1a;构建可靠的消息队列解决方案 引言前言Redis Streams的基本概念和特性1. 日志数据结构2. 消息和字段3. 消费者组4. 消息ID5. 实时和历史数据处理6. 性能…

7.3 uvm_config_db in UVM

uvm_config_db类派生自uvm_resource_db类。它是uvm_resource_db顶部的另一层便利层&#xff0c;简化了用于uvm_component实例的基本接口&#xff08;资源库的访问方法&#xff09;。 下面uvm_config_db类的代码段取自uvm源代码。 class uvm_config_db#(type Tint) extends uv…

html之为什么使用表单,常用表单元素使用?

文章目录 一、为什么使用表单呢&#xff1f;二、常用表单元素使用三、总结 一、为什么使用表单呢&#xff1f; 为什么使用表单呢&#xff0c;使用表单是为了更好的收集用户数据&#xff0c;并且安全 二、常用表单元素使用 1、password密码框 密码框&#xff1a;会隐藏数据&a…

网络摄像头爆破实战

*** 重要说明&#xff1a;仅用于交流网络安全测试技术&#xff0c;并唤起大家对网络安全的重视&#xff0c;如用本文的技术干违法的事情&#xff0c;博主概不负责。*** 文章目录 前言1. 发现摄像头2. 发现端口3. 确定品牌信息4. 确定RTSP地址5. 获取视频流6. 获取密码7. 再次获…

flutter学习-day20-使用SafeArea组件处理各机型的安全距离

&#x1f4da; 目录 介绍分析示例和效果图特殊情况 1. 介绍 安全区域&#xff0c;指的是移动端设备的可视窗口范围。处于安全区域的内容不受圆角、刘海屏、iPhone 小黑条、状态栏等的影响&#xff0c;也就是说&#xff0c;我们要做好适配&#xff0c;必须保证页面可视、可操作…

亚马逊鲲鹏系统全自动化操作注册下单更快捷

亚马逊鲲鹏系统的强大崛起&#xff0c;让买家号的注册、养号、下单留评等繁琐任务迎来了一场全新的自动化革命。这一创新性软件系统的横空出世&#xff0c;为广大亚马逊卖家提供了一种高效、智能的解决方案&#xff0c;成功摆脱了繁重的手动操作。 在这一系统中&#xff0c;买家…