当前位置: 首页 > 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…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...