C++要点细细梳理(下)(内存分配、异常处理、template和文件读写)

4. 类动态内存分配

4.1 C语言动态内存分配:malloc和free

在这里插入图片描述

4.2 C++动态内存分配:new和delete

  • 思考:定义一个对象和定义一个普通变量有何区别?
    • 普通变量:分配足够空间即可存放数据
    • 对象:除了需要空间,还要构造/析构
  • 类比:
    • malloc/free:租用一个仓库->存放货物 ->货物卖完 ->退租走人
    • new/delete:租一块地 ->修建大厦 (构造)->到期不用了 ->爆破拆除善后(析构) ->地归原主
      在这里插入图片描述
  • 调用默认构造函数,那么new+类名即可
  • 调用带参数的构造函数,那么new+类名(参数)
    在这里插入图片描述

4.2.1 new[ ]与delete[ ]运算符

  • new[ ]:申请空间并批量构造对象数组,返回首元素指针
  • delete[ ]:批量析构对象数组并释放空间,只能用于new[ ]出来的指针
    在这里插入图片描述

4.2.2 malloc/free和new/delete的区别

在这里插入图片描述

4.2.3 虚析构函数

4.2.3.1 内存泄漏和内存溢出
  • 内存溢出

  • 内存泄漏
    在这里插入图片描述

4.2.3.2 虚析构函数

在这里插入图片描述
在这里插入图片描述

4.3 例题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. 异常处理

5.1 异常与bug

在这里插入图片描述
在这里插入图片描述

异常与bug的区别

  • 对于Bug:程序员可控,越用心进行开发/走查/测试,Bug越少
  • 对于Exception:程序员不可控,需要代码中设置针对异常情况的保护措施
    • 网络应用:网络连通性、时延等不可控因素对于程序来说是异常
    • 游戏:玩家打出极限操作、突破预先设置的情况是异常
    • 数据分析:数据缺失值、未曾料想的特殊值等情况是异常
    • 等等
      • 除以0异常(不除以0就是正常的)
      • 空指针异常(指针不空就是正常的)
      • 数组越界异常(数组不越界就是正常的)
      • int溢出异常(int不太大就是正常的)

总之,程序正确编译了,也能按照既定逻辑执行功能,但是遇到了合法范围外的数据导致程序失去确定性而中断就是异常

5.2 异常处理

异常会导致程序失去确定性,不知道怎么继续下去,于是有异常保护:

  • 异常保护:引导程序继续走下去,再不济也要做好收尾工作,体面结束
    在这里插入图片描述

5.2.1 throw和try-catch

  • throw:使用throw语句主动立即抛出一个异常对象(但不一定throw才抛异常,如n/0)
    • throw抛出异常后会直接去执行catch对应的语句,原来异常语句下面的不会执行
  • try:保护一个语句块,后跟一个或多个catch块。try块中抛出异常不会立刻中止程序而是寻找catch处理
  • catch:捕获指定异常并进行处理,处理完不会再返回try块,直接离开try-catch继续执行

5.2.2 多个catch,捕获顺序:从详到略

在这里插入图片描述

5.2.3 多层函数调用中抛出异常

在这里插入图片描述

  • 当前层函数无法处理异常就结束此层,在稍外层继续抛出该异常,如果还是无法解决继续向更外层抛出异常,直到到达某层函数能够处理该异常,处理完毕后继续执行处理该异常的函数调用层

5.2.4 函数异常限定符

在这里插入图片描述

5.3 C++标准异常类

  • 虽说我们可以手动throw,抛出什么都可以,但一些常见的程序错误是C++自身抛出的(如除以零)
  • C++根据错误分类根据预设了一系列标准异常,定义在<exception>中
  • 它们以父子类层次结构组织,都在名字空间 std 下

5.3.1 自定义异常类

  • 自定义异常类通常继承自std:exception,并重写一些方法,比如what()
  • 通常在自己编写的程序中会根据业务需求自定义异常类
    在这里插入图片描述

5.4 例题

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

6. 模板

6.1 模板与泛型思想

6.1.1 函数重载为了实现代码复用做出的努力与不足

在这里插入图片描述

6.1.2 模板编程的目的

  • 回顾:从函数 ->函数重载 ->面向对象 ->继承/多态 ->… 核心目的?
    • 代码复用
  • 但以上技术仍然是类型依赖的,需要为不同类型进行相应的实现,如函数重载
  • 即“数据类型”信息是一个超参数,代码逻辑依赖这个超参数信息
  • 模板编程:类型参数化,将类型信息也视作一个普通参数,使代码逻辑与类型信息分离

在这里插入图片描述

6.2 模板函数

  • 用模板函数对不同类型变量进行自定义的拼接相加
    • template 关键字:表明接下来定义一个模板
    • typename 关键字:表明该模板参数是一个类型名——>模板参数可以不是同一个类型
    • T1、T2:是两个类型形式参数,是类型占位符
  • 于是在myAdd函数中就可以用T1和T2指代数据类型,编写代码逻辑
    在这里插入图片描述

模板函数实例化

在这里插入图片描述
在这里插入图片描述

  • 如果传入不支持类型的参数,将会报编译错误

模板类型推断

在这里插入图片描述

模板参数可以用于返回值

在这里插入图片描述

6.3 模板类

在这里插入图片描述

非类型的模板参数

在这里插入图片描述

模板类的声明与定义不可分离

  • 普通类可以模块化:在.h中声明,在.cpp 中定义(实现)
  • 但模板类不可以这样操作,必须声明同时+定义,为什么?
  • 因为编译器无法事先知道类型占位符T是什么,所以必须同时写

6.4 例题

  • 模板的核心思想:类型参数化,不依赖数据类型来编写程序逻辑
  • 模板可用于函数和类的编写:模板函数和模板类
  • template:声明模板,typename:定义模板的类型参数
    在这里插入图片描述
    在这里插入图片描述

7. 文件读写流

7.1 文件读写流

  • 回顾:cin 和 cout 叫做标准输入输出流对象,其机制类似一条河流
  • 事实上,文件I0和使用cin/cout没有本质区别,标准I0只是文件I0的一个特例
  • 文件输入输出流就是这条河流的来源/终点是一个文件

从标准IO到文件IO

  • 现在我们知道cout是一个对象而<<是运算符重载,含义实际上是 cout.插入(“hello”
  • cout 是标准输出流对象因此输出到控制台,如果换成文件输出流对象,就实现了往文件输出,输入流同理
    在这里插入图片描述

文件IO:打开->读/写->关闭

在这里插入图片描述

文件IO:fstream

  • 读文件要用ifstream对象,写文件要用ofstream对象,能不能就用一个流对象,又能读又能写?
  • std::fstream
    在这里插入图片描述
#include <iostream>
#include <fstream>
int main() {
    std::ifstream fin;
    std::ofstream fout;
    fin.open("input.txt",std::ios::in);
    fout.open("output.txt",std::ios::out);

    if (fin.is_open()==false||fout.is_open()==false){
        std::cout<<"Error"<<std::endl;
        return 0;
    }
    std::string name;
    int id;
    float score;

    while (fin.eof()==false){
        fin>>name>>id>>score;
        fout<<id<<" "<<name<<" "<<score<<std::endl;
    }

    fin.close();
    fout.close();

    return 0;
}

7.2 二进制文件读写

  • 思考:通过文本文件存储整数123456789需要多少空间?
  • 在文本文件中,将被存放成字符串“123456789”,共占9个字节
  • 但它本来是个int,只占4字节呀!直接把这4字节写入文件就好了
  • 二进制文件:将数据在内存中的实际存储内容直接写入到文件中,读取时需要知道存储和理解的格式
  • 文本文件:将数据作为一串字符逐一输出到文件中,读取时再按照ASCII码逐字符解读为文本
    在这里插入图片描述
#include <iostream>
#include <fstream>
int main() {
    std::ofstream  fout("data.bin",std::ios::out|std::ios::binary);
    if (!fout.is_open()){
        std::cerr << "Error opening file" << std::endl;
        return 1;
    }
    int a = 10;char b = 'a';;float c = 3.14;
    fout.write(reinterpret_cast<char*>(&a),sizeof(a));
    fout.write(reinterpret_cast<char*>(&b),sizeof(b));
    fout.write(reinterpret_cast<char*>(&c),sizeof(c));
    fout.close();

    std::ifstream fin;
    fin.open("data.bin",std::ios::in|std::ios::binary);
    if (!fin.is_open()){
        std::cerr << "Error opening file" << std::endl;
        return 1;
    }
    int a1;char b1;float c1;
    fin.read(reinterpret_cast<char*>(&a1),sizeof(a1));
    fin.read(reinterpret_cast<char*>(&b1),sizeof(b1));
    fin.read(reinterpret_cast<char*>(&c1),sizeof(c1));
    std::cout << a1 << std::endl << b1 << std::endl << c1 << std::endl;
    fin.close();
    
    return 0;
}

7.3 输出格式控制——流操作算子

  • 在C语言中,通过printf()/fprintf()函数的格式控制符控制输出的格式
  • 而在C++中,文件被封装成了流对象,控制流对象的格式,就能控制输出的格式
  • 通过往流对象中插入流格式控制符控制流对象的输出格式
  • 如希望控制输出小数时保留小数点后两位:
    在这里插入图片描述

常用的流格式控制符

在这里插入图片描述
在这里插入图片描述

7.4 例题

  • 文件在C++中以流对象的形式存在,通过流对象读写文件
  • 文件输入流:ifstream文件输出流:ofstream文件读写流:fstream
  • 流对象可以构造同时打开文件,也可以先定义,再调用open打开

在这里插入图片描述

  • 打开文件时要注意使用正确的相对路径或绝对路径
  • 操作流对象之前,要通过其is open 方法判断是否打开成功

在这里插入图片描述
在这里插入图片描述

  • 读文件时,通过流对象的 eof()方法判断是否已经读到文件尾了
  • eof即end of file
    在这里插入图片描述
  • 通过头文件中的流操作算子控制输出格式

在这里插入图片描述

  • 以二进制模式读写文件将直接拷贝实际存储内容,需要自行编码解码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8. 番外:C与C++

C和C++是两种非常相关的编程语言,它们之间存在许多关联,但也有很多显著的差异。

关联:

  1. 起源:C++是C语言的一个超集,也就是说,几乎所有的C语言代码都可以直接在C++中编译和运行。C++的创造者Bjarne Stroustrup在设计C++时,主要的目标之一就是提供一个“更好的C”,这意味着C++保持了C语言的许多特性,并增加了许多新的特性。
  2. 基础语法:C和C++的基本语法非常相似,包括变量声明、条件语句、循环语句等。
  3. :许多C语言的库在C++中仍然可用,尽管C++也提供了许多新的库和功能。

异同:

  1. 类型系统:C++是一种强类型语言,提供了更复杂的类型系统,包括类和对象,而C语言主要基于函数和指针。
  2. 面向对象:C++是一种面向对象的语言,支持类、继承、封装和多态等概念。而C语言主要是面向过程的。
  3. 异常处理:C++提供了异常处理机制,而C语言没有内置的异常处理机制,通常通过错误码和错误处理函数来处理错误。
  4. 模板:C++支持模板,这使得用户可以创建泛型函数和类,提高了代码的重用性。而C语言没有模板的概念。
  5. 运算符重载:C++允许用户重载运算符,以支持自定义类型的特殊运算。而C语言不支持运算符重载。

  1. 内存管理:在C和C++中,程序员都需要直接管理内存,包括分配和释放。这可能会导致内存泄漏等问题,需要程序员小心处理。
  2. 跨平台性:C和C++都是跨平台的语言,可以在多种操作系统和硬件平台上运行。
  3. 性能:由于C和C++都接近硬件,且没有运行时的解释或虚拟机开销,因此它们通常都能提供很高的性能。

总的来说,C和C++在许多方面都非常相似,但C++提供了更多的功能和特性,使得程序员可以编写更复杂、更灵活的程序。然而,这也增加了C++的学习曲线和复杂性。选择使用哪种语言通常取决于项目的具体需求和开发团队的技能。

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

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

相关文章

关于 VScode, 点击文件右键或者在文件夹中没有 【 在vscode中打开选项】 解决办法

关于 VScode, 点击文件右键或者在文件夹中没有 【 在vscode中打开选项】 解决办法 段子手-168 2024-4-6 1、在任意位置创建一个文本文件。如&#xff1a;a.txt 2、复制以下代码到 a.txt 文本文件中。 &#xff08;注&#xff1a; 以 ; 开头的 , 是备注信息 , 不需要做任何修…

代码随想录第19天

654. 最大二叉树 已解答 中等 相关标签 相关企业 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀…

影院座位选择简易实现(uniapp)

界面展示 主要使用到uniap中的movable-area&#xff0c;和movable-view组件实现。 代码逻辑分析 1、使用movable-area和movea-view组件&#xff0c;用于座位展示 <div class"ui-seat__box"><movable-area class"ui-movableArea"><movab…

【QT学习】5.控件

一。控件的了解 1.控件作用 拖拽页面&#xff0c;所见即所得。 2.创建控件 3.向qt项目中添加资源 3.1显示图片 项目右键--》add new 创建结果&#xff1a; 添加资源到文件中 补充&#xff1a;使用代码的方式添加图片 3.2显示动图 1.添加动图资源 添加资源 2.显示动图 3.3显示…

基于单片机电子硬币储存器的设计

**单片机设计介绍&#xff0c;基于单片机电子硬币储存器的设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机电子硬币储存器的设计概要主要涵盖了硬件设计、软件设计、硬币识别、计数与储存等核心功能。以下是对该设…

OWASP TOP10 漏洞详解

前言 该内容是 OWASP TOP 10 的学习笔记&#xff0c;笔记内容来源 B 站龙哥的视频【12.Top漏洞10&#xff1a;服务器请求伪造_哔哩哔哩_bilibili】 一、访问控制崩溃 概念 未对通过身份验证的用户实施恰当的访问控制。攻击者可以利用这些缺陷访问未经授权的功能或数据&#xf…

【Linux】环境基础开发工具使用——gcc/g++使用

Linux编译器-gcc/g使用 1. 背景知识 1. 预处理&#xff08;进行宏替换 ) 2. 编译&#xff08;生成汇编 ) 3. 汇编&#xff08;生成机器可识别代码&#xff09; 4. 连接&#xff08;生成可执行文件或库文件 ) 2. gcc如何完成 格式 gcc [ 选项 ] 要编译的文件 [ 选…

阿德勒、荣格、埃里克森、霍妮、弗洛姆、沙利文的新精神分析理论

新精神分析理论&#xff0c;强调自我的自主性及其整合与调节功能&#xff0c;强调文化和社会因素对人格的重大影响。 一、阿德勒的个体心理学 阿德勒&#xff0c;是一个男人努力克服自卑感的优秀样板。阿德勒写了《超越与自卑》。 阿德勒&#xff0c;向意识层面扩展精神分析…

c++11的重要特性3

目录 1、lambda表达式 C98中的一个例子 lambda表达式的 lambda表达式语法 函数对象与lambda表达式 3、可变参数模板 递归获取 逗号表达式展开参数包 2、包装器 function包装器 bind 1、lambda表达式 C98中的一个例子 在C98中&#xff0c;如果想要对一个数据集合中的元素进…

NetSuite 自定义记录类型的权限控制

在近期的一个定制项目中&#xff0c;遭受了一次用户洗礼。有个好奇宝宝把我们的一个自定义类型的表记录进行了删除&#xff0c;导致一个重要功能失败。算是给我们扎实上了一课。自定义类型的权限也需要重视起来。所以&#xff0c;今朝我们记录下这个设置&#xff0c;同时写给未…

C++ setw() 函数

C setw() 函数 分类 编程技术 C setw() 函数用于设置字段的宽度&#xff0c;语法格式如下&#xff1a; setw(n) n 表示宽度&#xff0c;用数字表示。 setw() 函数只对紧接着的输出产生作用。 当后面紧跟着的输出字段长度小于 n 的时候&#xff0c;在该字段前面用空格补齐&…

《QT实用小工具·十五》多种样式的开关控件

1、概述 源码放在文章末尾 目前实现了三种样式的开关控件按钮&#xff0c;如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef IMAGESWITCH_H #define IMAGESWITCH_H/*** 图片开关控件 * 1. 自带三种开关按钮样式。* 2. 可自定义开关图片。*/#include <QWid…

SpringBoot新增员工模块开发

需求分析与设计 一&#xff1a;产品原型 一般在做需求分析时&#xff0c;往往都是对照着产品原型进行分析&#xff0c;因为产品原型比较直观&#xff0c;便于我们理解业务。 后台系统中可以管理员工信息&#xff0c;通过新增员工来添加后台系统用户。 新增员工原型&#xf…

Vue中如何使用Tailwind CSS样式?多次引用不成功?具体步骤怎么做?

一、安装Tailwind CSS和依赖 在你的Vue项目中安装Tailwind CSS及其依赖。你可以使用npm或yarn来安装。 npm install tailwindcsslatest postcsslatest autoprefixerlatest # 或者yarn add tailwindcsslatest postcsslatest autoprefixerlatest 二、初始化Tailwind CSS np…

Linux常用命令-网络管理

文章目录 ping基本用法主要选项常见用途和理解输出注意事项 ifconfig基本用法配置网络接口示例高级功能 netstat基本用法常用选项示例注意事项 wget主要特点基本用法常见选项 示例注意事项 curl主要特点基本用法常见选项 示例注意事项 参考资料在线文档和手册图书在线教程和指南…

YOLO-World:实时开放词汇对象检测(论文+代码)

目录 一、YOLO-World摘要以及主要贡献 1.1摘要 1.2主要贡献 二、YOLO-World模型创新点总结 2.1YOLO Detector 2.2Text Encoder 2.3Re-parameterizable Vision-Language PAN 2.4核心创新点总结 三、如何应用 3.1推理预测 3.2自定义词汇推理 3.3自定义词汇类别…

Struts2的入门:新建项目——》导入jar包——》jsp,action,struts.xml,web.xml——》在项目运行

文章目录 配置环境tomcat 新建项目导入jar包新建jsp界面新建action类新建struts.xml,用来配置action文件配置Struts2的核心过滤器&#xff1a;web.xml 启动测试给一个返回界面在struts.xml中配置以实现页面的跳转&#xff1a;result再写个success.jsp最后在项目运行 配置环境 …

C++从入门到精通——类的定义及类的访问限定符和封装

类的定义及类的访问限定符和封装 前言一、类的定义类的两种定义方式成员变量命名规则的建议示例 二、类的访问限定符和封装访问限定符访问限定符说明C为什么要出现访问限定符例题 封装例题 前言 类的定义是面向对象编程中的基本概念&#xff0c;它描述了一类具有相同属性和方法…

Atlas 200 DK开发者套件的网络连接

一、参考资料 Atlas 200 DK官方文档 二、常用操作 1. Micro SD制卡 在windows系统上&#xff0c;一键制卡的步骤与Atlas 200I DK类似&#xff0c;但步骤更简单&#xff0c;详细步骤请参考&#xff1a;Windows系统制卡 2. Atlas 200 DK与PC机通信 2.1 准备工作 准备一根安…

一些好玩的东西

这里写目录标题 递归1.递归打印数组和链表?代码实现原理讲解二叉树的 前 中 后 序位置 参考文章 递归 1.递归打印数组和链表? 平常我们打印数组和链表都是 迭代 就好了今天学到一个新思路–>不仅可以轻松正着打印数组和链表 , 还能轻松倒着打印(用的是二叉树的前中后序遍…