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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ChatGpt 使用fetch-event-source实现sse流式处理

microsoft/fetch-event-source 是一个由微软提供的库&#xff0c;用于在客户端和服务器之间建立基于 EventSource 的连接。EventSource 是一种 HTTP 协议&#xff0c;允许服务器向客户端推送实时事件流。该库提供了对 EventSource 协议的封装&#xff0c;使得在前端 JavaScript…

二维码门楼牌管理系统技术服务:革新城市标识管理的新篇章

文章目录 前言一、二维码门楼牌管理系统的诞生背景二、二维码门楼牌管理系统的技术优势三、二维码门楼牌管理系统的应用前景四、面临的挑战与问题五、结语 前言 在数字化、智能化的时代背景下&#xff0c;二维码门楼牌管理系统作为一种创新的技术服务&#xff0c;正逐渐改变着…

AIGC下一步:如何用AI再度重构或优化媒体处理?

让媒资中“沉默的大多数”再次焕发光彩。 邹娟&#xff5c;演讲者 编者按 AIGC时代下&#xff0c;媒体内容生产领域随着AI的出现也涌现出更多的变化与挑战。面对AI的巨大冲击&#xff0c;如何优化或重构媒体内容生产技术架构&#xff1f;在多样的应用场景中媒体内容生产技术又…

springboot基于web的酒店客房管理系统论文

基于web的酒店客房管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了酒店客房管理系统的开发全过程。通过分析酒店客房管理系统管理的不足&#xff0c;创建了一个计算机管理酒店客房管理系统的方案。文…

锐捷网络携数据中心、以太全光等创新解决方案亮相2024MWC

在西班牙巴塞罗那举行的2024年世界移动通信大会(MWC)上,锐捷网络(下文简称“锐捷”)展示了将技术与应用充分融合的云数据中心、5G、光网络等产品及解决方案,帮助更多行业组织建设更贴近业务、智能、简单、高效、绿色低碳的网络基础设施,应对当下及未来的挑战,共同连接更广阔可能…

ceph性能测试

查看集群状态 ceph -s查看osd情况 ceph osd tree创建pg_num为60的pool&#xff0c;名为test。 ceph osd pool create test 60rados bench用于测试rados存储池底层性能&#xff0c;该工具可以测试写、顺序读、随机读三种类型 rados bench -p <pool_name> <seconds&…

[物联网] OneNet 多协议TCP透传

[物联网] OneNet 多协议TCP透传 STM32物联网–ONENET云平台的多协议接入产品创建 : https://blog.csdn.net/qq_44942724/article/details/134492924 Onenet tcp 透传 : https://blog.csdn.net/flyme2010/article/details/107086001 tcp服务端测试工具 : http://tcp.xnkiot.com/…

Day12-【Java SE进阶】JDK8新特性:Lambda表达式、方法引用、常见算法、正则表达式、异常

一、JDK8新特性 1.Lambda表达式 Lambda表达式是JDK 8开始新增的一种语法形式;作用:用于简化名内部类的代码写法。 注意:Lambda表达式并不是说能简化全部匿名内部类的写法&#xff0c;只能简化函数式接口的匿名内部类。 有且仅有一个抽象方法的接口。注意:将来我们见到的大部…

IntelliJ IDEA 2023 点击推送至远程仓库发生报错

开始我是直接在IDEA里创建的本地仓库&#xff0c;然后在gitee上的仓库是创建并初始化的&#xff0c;因为你点击初始化后&#xff0c;会默认帮你执行一些代码&#xff0c;然后你再在本地仓库推送至远程仓库就会出现不一致的情况。 当你本地的仓库与远程仓库中的内容不同步时&…

echarts vue 动画效果的水球图、波浪图教程

1、安装插件 前提是已经安装了echarts&#xff08;我的版本是4.2.1&#xff09; npm install echarts-liquidfill --save 我安装了3.1.0版本的&#xff0c;结果运行时报错"TypeError: wave.ensureState is not a function" 原因&#xff1a;echarts版本和echarts-l…

基于JAVA的聊天(ICQ)系统的设计于实现

一、绪论 ICQ是英文"I seek you "的简称&#xff0c;中文意思是我找你。ICQ最大的功能就是即时信息交流&#xff0c;只要记得对方的号码&#xff0c;上网时可以呼他&#xff0c;无论他在哪里&#xff0c;只要他上网打开ICQ&#xff0c;人们就可以随时交流。ICQ源于以…

GenAI助力DevOps,塑造软件工程的未来

自 2022 年以来&#xff0c;GenAI 无疑已成为一种普遍的技术趋势。在本文中&#xff0c;我们将探索 DevOps 中令人兴奋的 GenAI 领域&#xff0c;讨论其潜在优势、局限性、新兴趋势和最佳实践&#xff0c;深入了解 AI 支持的 DevOps 前沿世界&#xff0c;并探索这一强大组合如何…

Redis的主从搭建

1.准备两台机器&#xff0c;安装好redis 2.修改从服务器的redis配置 slaveof <masterip> <masterport>两个参数 masterip 主的ip 主的端口号 masterport 3. 启动redis 1.先启动主机redis 2.再启用从机redis 主机redis日志打印 从机redis 日志打印

水经微图Web版1.6.0发布

让每一个人都有自己的地图&#xff01; 水经微图&#xff08;简称“微图”&#xff09;新版已上线&#xff0c;在该版本中主要新增了点线面图层分组样式设置、图层排序并按序绘制、KML支持矢量符号的存储、KML支持态势标绘要素存储和新增历史地图文本样式等。 现在&#xff0…

Tomcat相关基础以及安装运行

目录 一、web概念 二、常见的web服务器 三、Tomcat 安装 下载&#xff1a; 安装&#xff1a; 四、Tomcat 目录结构 五、Tomcat 启动停止 一、web概念 软件架构&#xff1a; B/S&#xff1a; 浏览器/服务器端 ‐‐‐‐‐‐‐‐‐‐‐‐> 京东&#xff0c;网易&#xff0c…

[技巧]Arcgis之图斑四至点批量计算

前言 上一篇介绍了arcgis之图斑四至范围计算&#xff0c;这里介绍的图斑四至点的计算及获取&#xff0c;两者之间还是有差异的。 [技巧]Arcgis之图斑四至范围计算 这里说的四至点指的是图斑最东、最西、最南、最北的四个地理位置点坐标&#xff0c;如下图&#xff1a; 四至点…

Web组态可视化编辑器 快速绘制组态

随着工业智能制造的发展&#xff0c;工业企业对设备可视化、远程运维的需求日趋强烈&#xff0c;传统的单机版组态软件已经不能满足越来越复杂的控制需求&#xff0c;那么实现Web组态可视化界面成为了主要的技术路径。 行业痛点 对于软件服务商来说&#xff0c;将单机版软件转变…

禅道:提bug、管理case 7.0

一、禅道的介绍 &#xff08;1&#xff09;定义禅道是一个项目管理工具&#xff0c;也是一个bug管理工具&#xff0c;还是一个用例管理工具。 &#xff08;2&#xff09;作用&#xff1a;为了解决众多企业在管理中出现混乱&#xff0c;无序的现象&#xff0c;开发出来 &…

Java智慧云HIS医院信息化系统源码 更具灵活性、扩展性

目录 什么是云HIS 趋势与转变 HIS上云后有哪些好处 解决方案 云HIS组成 1、门诊挂号 2、住院管理 3、电子病历 4、药物管理 5、统计报表 6、综合维护 7、运营运维 什么是云HIS 云HIS是一种基于云计算技术的医院信息管理系统。云HIS可以帮助医院管理各类医院信息&a…

工作电压范围宽的国产音频限幅器D2761用于蓝牙音箱,输出噪声最大仅-90dBV

近年来随着相关技术的不断提升&#xff0c;音箱也逐渐从传统的音箱向智能音箱、无线音箱升级。同时在消费升级的背景下&#xff0c;智能音箱成为人们提升生活品质的方式之一。智能音箱是智能化和语音交互技术的产物&#xff0c;具有点歌、购物、控制智能家居设备等功能&#xf…