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++的学习曲线和复杂性。选择使用哪种语言通常取决于项目的具体需求和开发团队的技能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

路由策略与路由控制之双点双向重发布(OSPF-ISIS)实验

双点双向重发布在路由协议中&#xff0c;特别是在OSPF&#xff08;开放式最短路径优先&#xff09;与IS-IS&#xff08;中间系统到中间系统&#xff09;等协议之间&#xff0c;指的是在两个协议间或者两个进程间进行路由信息共享的机制。这种机制涉及到在两个不同的协议区域使用…

isc-dhcp-server DNS配置

我遇到一个有趣的问题&#xff0c;我先在一台Ubuntu服务器上使用isc-dhcp-server在其其中一个网口运行DHCP服务&#xff0c;然后我自己的笔记本电脑直连到这个网口&#xff0c;来上网。 本来直接就应该能上网&#xff0c;但是我的电脑只有在打开Clash时才能访问互联网&#xf…

【STL】栈

笔者在做下面这道题的时候想到用栈&#xff0c;但写的很麻烦 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define MAXC 255 typedef int SElemType; typedef struct StackNode {SElemType data;struct StackNode *next; }StackNode,*LinkStack; bool…

手机扫码获取文件怎么做?文件活码在电脑上的制作方法

现在很多人会把文件生成二维码之后&#xff0c;将二维码图片打印或者分享给其他人&#xff0c;通过扫描二维码的方式快速在手机上查看或者下载文件内容&#xff0c;从而提升文件传输的速度和效率。 制作文件活码二维码可以长期有效的扫码显示文件&#xff0c;支持多个文件存入…

如果在 Ubuntu 系统中两个设备出现两个相同的端口号解决方案

问题描述&#xff1a; 自己的移动机器人在为激光雷达和IMU配置动态指定的端口时&#xff0c;发现激光雷达和深度相机配置的 idVendor 和 idProduct 相同&#xff0c;但是两个设备都具有不同的ttyUSB号&#xff0c;如下图所示 idVendor&#xff1a;代表着设备的生产商ID,由USB设…

Linux第5课 Linux目录介绍

文章目录 Linux第5课 Linux目录介绍一、打开系统目录二、查看系统目录 Linux第5课 Linux目录介绍 系统目录就是指操作系统的主要文件存放的目录&#xff0c;目录中的文件直接影响到系统是否正常工作&#xff0c;了解这些目录的功能&#xff0c;对使用系统会有很大的帮助。 一…

c# wpf XmlDataProvider 简单试验

1.概要 2.代码 <Window x:Class"WpfApp2.Window12"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend…

NIO基础知识

在学习Netty之前先要学习一下NIO相关的知识&#xff0c;因为Netty是基于NIO搭建的一套网络编程框架。 一. NIO 基础 non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream&#xff0c;它就是读写数据的双向通道&#xff0c;可以从…

Oracle 中 where 和 on 的区别

1.Oracle 中 where 和 on 的区别 on&#xff1a;会先根据on后面的条件进行筛选&#xff0c;条件为真时返回该行&#xff0c;由于on的优先级高于left join&#xff0c;所以left join关键字会把左表中没有匹配的所有行也都返回&#xff0c;然后生成临时表返回,执行优先级高于…

计算机接口(部分实验)

;实验三&#xff1a; ;*******************************; ;* 8255方式0的C口输入,A口输出 *; ;*******************************; io8255a equ 288h io8255c equ 28ah io8255 equ 28bhcode segmentassume cs:code start: mov dx, 28bH ;设8255为…

FPGA高端项目:解码索尼IMX327 MIPI相机+2路视频融合叠加,提供开发板+工程源码+技术支持

目录 1、前言2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX327 及其配置MIPI CSI RX图像 ISP 处理HLS多路视频融合叠加图像缓存HDMI输出工程…

【51单片机入门记录】RTC(实时时钟)-DS1302应用

目录 一、DS1302相关写函数 &#xff08;1&#xff09;Write&#xff3f;Ds1302 &#xff08;2&#xff09;Write&#xff3f;Ds1302&#xff3f;Byte 二、DS130相关数据操作流程及相关代码 &#xff08;1&#xff09;DS1302初始化数据操作流程及相关代码 (shijian[i]/10&…

20240406在Ubuntu20.04下让移远的4G模块EC200A-CN通过USB底板直接上网

20240406在Ubuntu20.04下让移远的4G模块EC200A-CN通过USB底板直接上网 2024/4/6 15:42 缘起&#xff1a;最近在调试全志H3平台在linux&#xff08;Ubuntu Core/openWRT&#xff09;下适配EC200A-CN。 以前调试移远的EC20的时候是先在Ubuntu下确认模块时好的&#xff0c;然后再开…

最新在线工具箱网站系统源码

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 系统内置高达72种站长工具、开发工具、娱乐工具等功能。此系统支持本地调用API&#xff0c;同时还自带免费API接口&#xff0c; 是一个多功能性工具程序&#xff0c;支持后台管理、上…

蓝凌OA单点登录实现方案:以统一身份管理提升效率与安全新举措

蓝凌OA的优势与挑战 在数字化浪潮的推动下&#xff0c;企业对于高效、安全的身份管理需求愈发迫切。蓝凌OA系统&#xff0c;以其出色的流程管理和协同办公能力&#xff0c;已经成为众多企业实现数字化转型的重要工具。然而&#xff0c;随着企业信息化建设的不断深入&#xff0…

配置vscode链接linux

1.安装 remote SSH 2.按F1 ssh ljh服务器公网ip 3. 选择保存远端host到本地 某位置 等待片刻后 4. 切换到远程资源管理器中 应该可以看到一台电脑&#xff0c;右键在当前窗口链接&#xff0c;输入你的服务器用户密码后电脑变绿说明远程连接成功 5.一定要登陆上云服务器后再…

错误:找不到或无法加载主类(vscode的解决方法)

项目场景&#xff1a; 某天&#xff0c;喵某人在敲代码的过程中&#xff0c;点击运行代码&#xff0c;突然显示找不到或无法加载主类。之前创建的java文件都可以正常运行。但新建的java文件无论是什么&#xff0c;点击运行都会显示“错误&#xff1a;找不到或无法加载主类”。 …

深入剖析:HTML页面从用户请求到完整呈现的多阶段加载与渲染全流程详解

HTML页面的加载全过程是一个涉及网络通信、文件解析、资源加载、渲染树构建、布局计算以及最终绘制等多个环节的复杂过程。以下是详细的步骤说明&#xff1a; 1. 用户输入URL并发送请求 用户在浏览器地址栏输入一个URL&#xff08;统一资源定位符&#xff09;&#xff0c;或者…

【内存泄漏】数据库连接connectionPhantomRefs内存过大

1. 问题背景 线上出现内存报警&#xff0c;内存增长曲线如下 dump内存文件&#xff0c;临时重新发布服务。后经排查发现是数据库连接池设置不合理以及mysql-connector-java 5.1.49有内存泄漏bug。以下为对此问题的分析及问题总结。 1.1 应用背景 数据库连接池&#xff1a; …

[StartingPoint][Tier1]Ignition

Task 1 Which service version is found to be running on port 80? (发现哪个服务版本在端口 80 上运行&#xff1f;) $ nmap -sV -Pn 10.129.1.27 -p 80 nginx 1.14.2 Task 2 What is the 3-digit HTTP status code returned when you visit http://{machine IP}/? (访…