C++的IO流和C++的类型转换----《Hello C++ Wrold!》(29)--(C/C++)

文章目录

前言

在 C++ 编程体系中,类型转换与 IO 流是支撑程序数据处理与交互的两大核心环节。类型转换关乎数据在不同类型间的安全传递与运算适配,而 IO 流则负责程序与外部设备(如键盘、屏幕、文件)之间的数据输入与输出,二者共同构成了 C++ 程序实现功能、交互信息的基础框架。​

C 语言中的类型转换方式虽简洁,却存在可视性差、难以追踪的问题,容易在复杂程序中引发潜在的逻辑错误。为解决这一痛点,C++ 引入了四种命名明确的强制类型转换操作符 ------static_cast、reinterpret_cast、const_cast与dynamic_cast,通过规范的语法形式,让类型转换过程更清晰、更可控,同时针对不同转换场景提供了精准的约束与支持。​

而在 IO 流领域,C++ 在兼容 C 语言 IO 函数的基础上,构建了更具面向对象特性的 IO 流体系。从用于控制台交互的istream(输入流)、ostream(输出流),到用于文件操作的ifstream(文件输入流)、ofstream(文件输出流)与fstream(文件读写流),再到用于字符串数据处理的stringstream,C++ 的 IO 流机制为不同场景下的数据传输提供了灵活、统一的接口,尤其对自定义类型的 IO 支持,更是大幅提升了代码的扩展性与复用性。​

本文将系统梳理 C++ 类型转换的四种操作符特性与使用场景,深入解析 IO 流体系的核心组件与实际应用方法,结合具体代码示例,帮助读者理解并掌握这两部分关键知识,从而在实际编程中更安全地处理类型转换、更高效地实现数据 IO 交互,提升代码的质量与开发效率。​

C++的类型转换

C语言的类型转换有隐式类型转换和强制类型转换

但是这个转换的可视性太差了--有时很难意识到发生了类型转换,最终导致运行结果和预期不符
所以在C++中引出了四种命名的强制类型转换操作符,来加强类型转换的可视性

static_castreinterpret_castconst_castdynamic_cast

四种命名的强制类型转换操作符

static_cast

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

cpp 复制代码
比如: double d = 20.25;
   int a = static_cast<int>(d);这样可以

但是
     int* p  = &a;
   int* address = static_cast<int*>(p);这样就不行
//<>括号里面填的是要转换成什么类型

reinterpret_cast

reinterpret_cast这个的话就是用于不同类型之间的转换

cpp 复制代码
比如上面的应该改成int* address = reinterpret_cast<int*>(p);

const_cast

const_cast的作用就是删除变量的const属性

cpp 复制代码
eg:
    const int n = 10;
   int* p2 = const_cast<int*>(&n);
p2指向n的地址


原C语言的写法:
        const int n = 10;
        int* p = (int*)(&n);//也有下面那个问题哈

但是要注意:

在用p2去改变n的值的时候,编译器可能会优化掉对n内存的访问操作--比如:用p2去改了n的值,但是程序运行时还是原来那个值

这个时候就需要volatile去让编译器每次都访问内存里的n

cpp 复制代码
volatile的用法:volatile修饰的变量,每次都要去内存中访问
 volatile  const int n = 10;
   int* p2 = const_cast<int*>(&n);

dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
1.dynamic_cast只能用于父类含有虚函数的类

2.dynamic_cast会检查是否能转换成功,能成功的话就就会转换,不能成功的话会返回空指针
如果是子类转换成父类的话,不需要dynamic_cast,用static_cast就行了

如果是父类转换成子类的话,用dynamic_cast--这是安全的,但不一定能转换成功

RTTI(这个了解一下就行了)

这个的意思就是进行运行时的类型识别
C++支持RTTI的方式有三种:

1.typeid运算符

2.dynamic_cast运算符

3.decltype

C++的IO流

istream是输入东西 ostream是输出东西

iostream是输入输出东西

cpp 复制代码
用法:
ostream& operator << (ostream& out, const Date& d)
{
	out << d._year << " " << d._month << " " << d._day;
	return out;

C语言的IO流里面主要用到的有fprintf fscanf printf scanf sprintf sscanf

C++当前也能用这些,但是自定义类型的话得用cin和cout才能支持
引申:如果程序一直要求输入的话,可以ctrl+z终止输入,当然ctrl+c也可以--自己一般用ctrl+z
ios流里面有个operator bool()的成员函数来判断输入输出流的状态:

cpp 复制代码
eg: 
if(cin>>nums)//其实是operator>>(cin,nums).operator bool()

C++文件的IO流

C语言文件的IO流同样可以使用哈

ifstream:专门用于从文件中读取数据,提供了打开、关闭文件以及读取文件内容的相关操作。

ofstream: 专门用于向文件中写入数据,提供了打开、关闭文件以及写入文件内容的相关操作。

fstream :结合了 ifstreamofstream 的功能,允许对同一个文件进行读写操作。

cpp 复制代码
用法:
eg:
ifstream ifs("text.txt", ios_base::in | ios_base::binary);
//text.txt是文件名
//ios_base::in | ios_base::binary是读取模式和二进制模式打开文件

ifs.read((char*)&info, sizeof(info));//读二进制
ifs>>info;//读文本

注意:

二进制读写不能用string,vector这样的对象存数据--这样写进去的只会是一个指针,如果进程结束了就成野指针了

stringstream

这个其实不常用,了解一下就行
eg:用途:

1.数据转换成字符串

cpp 复制代码
eg:
int a = 114514;
 string sa;
 stringstream s;
 s << a;
 s >> sa;

但是可以用to_string直接解决

2.序列化和反序列化结构数据(但是一般不用stringstream去实现)

相关推荐
悟空码字1 小时前
Kubernetes实战:你的分布式系统“保姆”养成记
java·后端·kubernetes
不想写笔记1 小时前
C语言 函数
c语言·笔记
稚辉君.MCA_P8_Java1 小时前
Gemini永久会员 哈希表(Hash Table)高效的数据结构
java·数据结构·后端·算法·架构
Gomiko1 小时前
JavaScript基础(七):数组
开发语言·javascript·ecmascript
一只乔哇噻1 小时前
java后端工程师+AI大模型进修ing(研一版‖day58)
java·开发语言
大海里的番茄1 小时前
让操作系统的远程管理更简单用openEuler+cpolar
linux·c语言·c++
Teroin1 小时前
LeetCode55 跳跃游戏
数据结构·算法·leetcode
lichong9511 小时前
Android 弹出进度条对话框 避免用户点击界面交互
java·前端·javascript
Geek__19921 小时前
杂记:记录一次Sqlite的使用问题
java·oracle·sqlite