当前位置: 首页 > news >正文

【C++】类型转换和IO流

目录

C语言中的类型转换

C++ eplicit && volatitle

eplicit

volatile

C++强制类型转换

static_cast(相关类型)

reinterpret_cast(不相关类型) 

const_cast(去掉const属性)

dynamic_cast

RTTI(了解)

IO流 


C语言中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与
接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换: 隐式类型
转换 显式类型转换
  1. 隐式类型转换:编译器在编译阶段自动进行,能转就转,不能转就编译失败
  2. 显式类型转换:需要用户自己处理。

 void Test ()

{
int i = 1 ;
// 隐式类型转换
double d = i ;
printf ( "%d, %.2f\n" , i , d );
int* p = & i
// 显示的强制类型转换
int address = ( int ) p ;
printf ( "%x, %d\n" , p , address );
}

缺陷:转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换。

C++ eplicit && volatitle

eplicit

自定义类型之间只要构造函数里面有联系也可以进行类型转换 

#include <iostream>

using namespace std;

class A
{
public:
    A(int a)
        :_a(a)
    {}
private:
    int _a;
};

class B
{
public:
    B(const A& a)
    {}
private:
    //……
};

int main()
{
    A a1(1);
    B b1 = a1;

    return 0;
}

如果不想这个转换发生可以在B 的构造函数前面加 explicit 关键字

class B
{
public:
    explicit B(const A& a)
    {}
private:
    //……
};

volatile

//这个n为常变量,不是常量,不能直接修改,但是可以通过类型转换间接修改  

const int n = 10;

//去掉const 属性后,常变量就可以修改
int* p = (int*)&n;
(*p)++;

//监视窗口中n已经变成11,但是打印为10

//原因是编译器的优化,去掉const 属性是有风险的,因此编译器所作的优化是在取n的值的

//时候没有从内存里取,而是从寄存器里取,有些编译器编译的时候会将const变量都替换成

//常量
cout << n << endl;    //10
cout << *p << endl;   //11

//要解决上述情况,需要引入 volatile 关键字

//该关键字的作用是告诉编译器每次都去内存中取值

volatile const int n = 10;

C++强制类型转换

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

static_cast 、reinterpret_cast、const_cast、dynamic_case

static_cast(相关类型)

static_cast 用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用
static_cast ,但它不能用于两个不相关的类型进行转换。
 
int main ()
{
double d = 12.34 ;
int a = static_cast < int > ( d );
cout << a << endl ;
return 0 ;
}

reinterpret_cast(不相关类型) 

reinterpret_cast 操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换
为另一种不同的类型
int main ()
{
        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 );
        return 0 ;
}

const_cast(去掉const属性)

const_cast 最常用的用途就是删除变量的 const 属性,方便赋值
void Test ()
{
volatile  const int a = 2 ;
int* p = const_cast < int* > ( & a );
* p = 3 ;
cout << a << endl ;
}

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

RTTI(了解)

RTTI Run-time Type identification 的简称,即:运行时类型识别。
C++ 通过以下方式来支持 RTTI
  1. typeid运算符
  2. dynamic_cast运算符
  3. decltype

IO流 

C++ 系统实现了一个庞大的类库,其中 ios 为基类,其他类都是直接或间接派生自 ios

 c++中自定义类型中重载流插入和流提取,方法如下示例:

class Date
{
        friend ostream & operator << ( ostream & out , const Date & d );
        friend istream & operator >> ( istream & in , Date & d );
public :
        Date ( int year = 1 , int month = 1 , int day = 1 )
                : _year ( year )
                , _month ( month )
                , _day ( day )
        {}
        operator bool ()
        {
// 这里是随意写的,假设输入 _year 0 ,则结束
                if ( _year == 0 )
                        return false ;
                else
                return true ;
        }
private :
        int _year ;
        int _month ;
        int _day ;
};
istream & operator >> ( istream & in , Date & d )
{
        in >> d . _year >> d . _month >> d . _day ;
        return in ;
}
ostream & operator << ( ostream & out , const Date & d )
{
        out << d . _year << " " << d . _month << " " << d . _day ;
        return out ;
}
// C++ IO 流,使用面向对象 + 运算符重载的方式
// 能更好的兼容自定义类型,流插入和流提取
int main ()
{
// 自动识别类型的本质 -- 函数重载
// 内置类型可以直接使用 -- 因为库里面 ostream 类型已经实现了
        int i = 1 ;
        double j = 2.2 ;
        cout << i << endl ;
        cout << j << endl ;
// 自定义类型则需要我们自己重载 << >>
        Date d ( 2022 , 4 , 10 );
        cout << d ;
        while ( d )
        {
                cin >> d ;
                cout << d ;
        }
        return 0 ;
}

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

下面我们cin常用来读取数据直到输入结束,本质就是重载类型 

#include <iostream>

using namespace std;

int main()
{
    int num;

    // while(cin>>a>>b) cin.operator>>(a).operator>>(b).operator bool()
    while (cin >> num) //operator >>(cin,str). operator bool()
    {
        //……
    }
    return 0;
}

自定义类型 和 内置类型相互转换

#include <iostream>

using namespace std;

class A
{
public:
     A(int a)
        :_a(a)
    {}

     //内置类型 <- 自定义类型

     operator int ()

     {

         return _a;

     }

  
private:
    int _a;
};

int main()
{

    //自定义类型 <- 内置类型
    A a = 1;

    //内置类型 <- 自定义类型,需要重载类型
    int num = a;
    return 0;
}

相关文章:

【C++】类型转换和IO流

目录 C语言中的类型转换 C eplicit && volatitle eplicit volatile C强制类型转换 static_cast(相关类型) reinterpret_cast(不相关类型&#xff09; const_cast&#xff08;去掉const属性&#xff09; dynamic_cast RTTI&#xff08;了解&#xff09; IO流 …...

leetCode刷题 5.最长回文子串

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#x…...

计算机组成原理面试题

计算机组成原理是计算机科学的基础课程之一&#xff0c;涉及计算机系统的基本结构和工作原理。以下是一些可能出现在面试中的计算机组成原理相关题目&#xff1a; 1. **什么是冯诺依曼体系结构&#xff1f;** - 冯诺依曼体系结构是一种计算机组织架构&#xff0c;它将程序指…...

「Mybatis深入三」:高级查询-模糊查询

一、需求 根据username 模糊查询user 表 二、代码演示 1、方式1 数据库环境 CREATE DATABASE mybatis_db; USE mybatis_db; CREATE TABLE user (id INT(11) NOT NULL AUTO_INCREMENT,username VARCHAR(32) NOT NULL COMMENT 用户名称,birthday DATETIME DEFAULT NULL COMMEN…...

LabVIEW管道缺陷智能检测系统

LabVIEW管道缺陷智能检测系统 管道作为一种重要的输送手段&#xff0c;其安全运行状态对生产生活至关重要。然而&#xff0c;随着时间的推移和环境的影响&#xff0c;管道可能会出现老化、锈蚀、裂缝等多种缺陷&#xff0c;这些缺陷若不及时发现和处理&#xff0c;将严重威胁到…...

java在cmd中乱码的问题解决

本文深入探讨了在使用 Java 命令行&#xff08;cmd&#xff09;时可能出现的中文乱码问题&#xff0c;并提供了两种解决方案。首先&#xff0c;通过临时的方式&#xff0c;用户可以执行命令 chcp 936 选择字符集&#xff0c;然后再运行 Java 命令&#xff0c;确保在选择字符集过…...

OpenHarmony教程指南—ArkUI中组件、通用、动画、全局方法的集合

介绍 本示例为ArkUI中组件、通用、动画、全局方法的集合。 本示例使用 Tabs容器组件搭建整体应用框架&#xff0c;每个 TabContent内容视图 使用 div容器组件 嵌套布局&#xff0c;在每个 div 中使用 循环渲染 加载此分类下分类导航数据&#xff0c;底部导航菜单使用 TabCont…...

第二证券|金价逼近历史高点 黄金股价值有望重估

经过两个多月的震荡后&#xff0c;黄金打响新一波攻势&#xff0c;期货商场价格已逼近前史高点。 有分析认为&#xff0c;虽然黄金价格短期已有显着涨幅&#xff0c;存在震荡或许&#xff0c;但中长时间看&#xff0c;跟着美联储钱银政策的转向&#xff0c;黄金价格仍有上行动…...

关于51单片机晶振定时问题

单片机中晶振频率为12MHZ的机器周期怎么算? 1、系统晶振频率是12M&#xff0c;则机器周期&#xff1d;12&#xff0f;12&#xff1d;1us&#xff1b; 2、定时1ms&#xff1d;1&#xff0a;1000&#xff1d;1000us&#xff1b; 3、工作在方式1下&#xff1a;最大计数值是2&a…...

NoSQL--2.MongoDB配置(Windows版)

目录 2.MongdoDB配置 2.1 Windows环境下操作 2.1.1 注册MongDB Atlas&#xff1a; 2.1.2 MongoDB Community Server Download&#xff1a; 2.1.3 启动MondgoDB服务&#xff1a; 2.1.3.1 命令行参数的方式启动MongoDB服务&#xff1a; 2.1.3.2 使用配置文件方式启动Mongo…...

HTML静态网页成品作业(HTML+CSS)——安徽宣笔设计制作(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 &#x1f3f7;️想要…...

MySQL CTEs通用表表达式:进阶学习-递归查询

MySQL CTEs通用表表达式&#xff1a;进阶学习-递归查询 递归通用表表达式是其会引用自身的通用表表达式。 CTEs 递归通用表表达式补上了MySQL8之前无法使用递归查询的空白。在之前&#xff0c;递归查询需要使用函数等方法实现。 基础使用&#xff0c;请参考前文&#xff1a; …...

[Java安全入门]二.序列化与反序列化

一.概念 Serialization&#xff08;序列化&#xff09;是一种将对象以一连串的字节描述的过程&#xff1b;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象&#xff0c;放入文件中保存就是序列化&#xff0c;将文件中的字节码重新转成对象就是反…...

Dutree:Linux 文件系统磁盘使用追踪工具

在 Linux 系统中&#xff0c;对文件系统的磁盘使用情况进行跟踪和管理是至关重要的。dutree 是一个功能强大的工具&#xff0c;它能够以可视化的方式展示文件系统中的目录和文件的大小&#xff0c;帮助用户更好地了解磁盘空间的使用情况。本文将介绍 dutree 工具的使用方法、功…...

http和https的区别是什么?

–前言 传输信息安全性不同、连接方式不同、端口不同、证书申请方式不同 一、传输信息安全性不同 1、http协议&#xff1a;是超文本传输协议&#xff0c;信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文&#xff0c;就可以直接读懂其中的信息。 2、h…...

学习Android的第十九天

目录 Android ExpandableListView 分组列表 ExpandableListView 属性 ExpandableListView 事件 ExpandableListView 的 Adapter 范例 参考文档 Android ViewFlipper 翻转视图 ViewFlipper 属性 ViewFlipper 方法 为 ViewFlipper 加入 View 例子&#xff1a;全屏幕可…...

C#上位机调试经验

1.使用Visual Studio的远程工具 因为上位机软件安装在工控机上&#xff0c;不方便调试。如果直接把代码放在工控机上&#xff0c;又不太安全。 可以在工控机上安装一个Visual Studio的远程工具&#xff0c;把随身带的笔记本电脑通过网线插在工控机上 这样可以在笔记本上使用…...

BUUCTF---[极客大挑战 2019]BabySQL1

1.这道题和之前做的几道题是相似的&#xff0c;这道题考的知识点更多。难度也比之前的大一些 2.尝试万能密码 or 1#发现过滤了or,使用1和1,发现他对单引号也进行了过滤。于是我尝试进行双写绕过&#xff0c;发现可以通过了。 3.由之前的做题经验可知&#xff0c;这道题会涉及到…...

0基础跨考计算机|408保姆级全年计划

我也是零基础备考408&#xff01; 虽说是计算机专业&#xff0c;但是本科一学期学十几门,真的期末考试完脑子里什么都不进的...基本都是考前一周发疯学完水过考试...&#x1f605; 想要零基础跨考可以直接从王道开始&#xff01;跟教材一点一点啃完全没必要&#x1f978; 现在…...

C# 操作LiteDB

1、很简单的东西不废话&#xff0c;直接上图上代码。 2、NuGet程序中根据自己的项目版本安装LiteDB,如下图&#xff1a; 3、程序运行加过如下图&#xff1a; 4、程序代码如下&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System…...

LeetCode 2917.找出数组中的 K-or 值:基础位运算

【LetMeFly】2917.找出数组中的 K-or 值&#xff1a;基础位运算 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数&#xff1a; 只有…...

MySQL窗口函数:从理论到实践

目录 1. ROW_NUMBER() 2. RANK() 3. DENSE_RANK() 4. NTILE(n) 5. LAG() 和 LEAD() 6. FIRST_VALUE() 和 LAST_VALUE() 总结 MySQL中的窗口函数&#xff08;Window Functions&#xff09;允许用户对一个结果集的窗口&#xff08;或分区&#xff09;执行计算&#xff0c;…...

Vue+SpringBoot打造考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…...

python基础第二天

世界杯小组赛成绩 注意&#xff1a; 1.循环 1.1while 1.2for 1.3 range 1.4 while else while 循环正常执行完才能执行else语句...

YOLOV9论文解读

代码&#xff1a;https://github.com/WongKinYiu/yolov9论文&#xff1a;https://arxiv.org/abs/2402.1361本文提出可编程梯度信息(PGI)和基于梯度路径规划的通用高效层聚合网络(GELAN)&#xff0c;最终铸成YOLOv9目标检测全新工作&#xff01;性能表现SOTA&#xff01;在各个方…...

【Spring】21 通过@Primary注解优化注解驱动的自动装配

文章目录 Primary注解简介优势和适用场景小结 Spring 框架提供了强大的依赖注入机制&#xff0c;其中 Autowired 注解是一种常用的方式。然而&#xff0c;当存在多个候选 bean 时&#xff0c;通过类型自动装配可能导致选择困难。为了更好地控制这一过程&#xff0c;Spring 引入…...

【HTML】HTML基础7.3(自定义列表)

目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…...

java设计模式课后作业(待批改)

此文章仅记录学习&#xff0c;欢迎各位大佬探讨 实验&#xff08;一&#xff09; 面向对象设计 实验目的 ①使用类来封装对象的属性和功能&#xff1b; ②掌握类变量与实例变量&#xff0c;以及类方法与实例方法的区别&#xff1b; 知识回顾 详情见OOP课件 实验内容…...

qt 语音引擎 QTextToSpeech Microsoft SAPI

QT中语音播报的代码 在QT中实现语音播报可以使用QTextToSpeech类&#xff0c;具体代码如下&#xff1a; #include <QCoreApplication> #include <QTextToSpeech> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创…...

react hook: useimperativeHandle

通过 useImperativeHandle&#xff0c;子组件可以选择性地暴露给父组件某些属性或方法&#xff0c;而不是将所有属性和方法暴露出去。 父组件 获得自组件的 ref&#xff0c;就能通过该 ref 来调用 focus来聚焦等功能 在 forwardRef 包装的组件中&#xff0c;ref 固定地是第二个…...