C++_22_异常

文章目录

  • 异常
    • 概念:
    • **抛出异常:**
        • 关键字:
    • **捕获异常:**
    • **栈解旋:**
    • **异常的接口声明:**
    • **异常对象的生命周期:**
      • 1 传递异常对象
      • 【不使用】
      • 2 传递异常对象指针
      • 【不使用】
      • 3 传递异常对象引用
      • 【**最优解**】
    • **异常的多态:**
    • 标准异常库:
    • 自定义异常类:【了解】
  • 最需注意的点:
    • 拷贝构造
    • 析构函数
  • 必须手动回收
    • 野指针与空指针
    • 虚函数与纯虚函数
    • 虚析构造与纯虚析构
    • 类模版

异常

概念:

程序中因硬件或代码编写时考虑不足导致的程序崩溃

硬件问题: 不予处理

代码编写考虑不足: 要处理

​ 分类:

  • 编译时错误: 语法错误导致
    运行时错误: 考虑不足导致

抛出异常:

关键字:

throw : 抛出

语法:

throw 数 据;

捕获异常:

语法:

try
{}
catch(数据类型1 变量名1)
{}
catch(数据类型2 变量名2)
{}
......

示例:

#include <iostream>
using namespace std;
void myDiv(int n01, int n02)
{//什么情况下抛出异常if (n02 == 0){// throw 1;throw 'a'; // 这里抛出的  就是catch 接收的值}
}
int main(int argc, char const *argv[])
{try{cout << "1111" << endl;myDiv(10, 0);cout << "222" << endl;}catch (int e){cout << "int 除0了" << endl;}catch (char e){cout << "char 除0了" << endl;}return 0;
}

注意:

> 如果在try中出现异常,其try中剩余代码将不在执行,进入对应的catch中
> catch中变量的值就是抛出异常时throw后的数据
> catch可以有多个

栈解旋:

只能解旋栈区的东西 堆区的没戏 new的 都得自己去释放

概念:

> 当try中出现异常,其异常代码之上创建的对象都会被释放
> 其释放顺序与创建顺序相反
> 这种情况称为栈解旋注意:new创建的对象在堆区,无法自动释放
#include <iostream>
using namespace std;
class Data
{
public:Data() {cout << "构造函数" << endl; }~Data() { cout << "析构函数" << endl; }
};
class Data02
{public:Data02() { cout << " Data02 构造函数" << endl; }~Data02() { cout << " Data02 析构函数" << endl; }
};
int main(int argc, char const *argv[])
{try{//Data *d01 = new Data();//Data02 *d02 = new Data02();Data02 d02;Data d01;throw 1;}catch (int e){cout << "xxxx" << endl;}return 0;
}

异常的接口声明:

语法:

返回值类型  函数名(形参列表)   throw (可能抛出的异常1 , 可能抛出的异常2 ,...)
{函数体;
}

注意:

如果 throw() 就是里面没东西

说明当前函数没用异常

throw() == noexcept   没有异常
// 异常的接口声明
#include <iostream>
using namespace std;
// 此时在VSCode会显示红色,但是语法没有问题
void myDiv(int x, int y) throw(int, char)
{if (y == 0){throw 1;}cout << x / y << endl;
}
int main(int argc, char const *argv[])
{try{myDiv(10, 0);}catch (int e){}catch (char e){}return 0;
}

异常对象的生命周期:

1 传递异常对象

【不使用】

缺点: 占用内存大

此时会触发拷贝构造,会形成一个新的异常对象,就得销毁这两个对象

示例:

#include <iostream>
using namespace std;
class MyException
{
public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;}
};
int main(int argc, char const *argv[])
{try{// MyException():创建了MyException的一个对象,该对象没有对象名,称为匿名对象throw MyException();}catch (MyException e){}return 0;
}

在这里插入图片描述

2 传递异常对象指针

【不使用】

缺点:会造成内存泄漏

传递异常对象,创建一次 但是不销毁 因为没delete

#include <iostream>
using namespace std;
class MyException
{
public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;}
};
int main(int argc, char const *argv[])
{try{// 传递的是指针throw new MyException();}catch (MyException *e){}return 0;
}

在这里插入图片描述

3 传递异常对象引用

最优解

传递异常对象引用,只会创建一次,而且可以自动销毁

示例:

#include <iostream>
using namespace std;
class MyException
{
public:MyException(){cout << "构造函数被调用" << endl;}MyException(const MyException &e){cout << "拷贝构造被调用" << endl;}~MyException(){cout << "析构函数被调用" << endl;}
};
int main(int argc, char const *argv[])
{try{// 传递的是异常对象的引用throw MyException();}catch (MyException &e){}return 0;
}

在这里插入图片描述

异常的多态:

注意:

1 抛出的子类异常,可以被父类异常类型接收
2 抛出的子类异常,catch 中 有父类异常与子类异常类型,此时按代码顺序书写接收,建议先子后父

示例

#include <iostream>
//  异常的多态
using namespace std;
class MyException {};
class NullException : public MyException {};
int main(int argc, char const *argv[])
{try{throw NullException();}catch (NullException &e){cout << "NullException" << endl;}catch (MyException &e){cout << "MyException" << endl;}return 0;
}

标准异常库:

概述:

由c++提供的一套异常相关的类

在这里插入图片描述

在这里插入图片描述

自定义异常类:【了解】

步骤:

  • 1 自定义异常类 使其继承于 exception 获得其子类

  • 2 定义一个变量记录异常信息

  • 3 定义该类的构造函数,拷贝构造,析构函数【只有析构需要判断是否为空,拷贝不用会重复释放野指针出现段错误】

  • 4 重写 what 函数

    const char* what() const noexcept
    {return 步骤2定义的变量   
    }
    
  • 注意

    编译使用需加	-std=c++11
    

最需注意的点:

拷贝构造

何时触发调用:

对象A以对象B进行初始化

如:

class Data {};
Data b;  //创建对象
Data a = b;  // 将b 赋值给a  对象b 以对象a进行初始化  就是a  b 都是单独的method(Data d)
{
}
method(b);//Data d = b;  将 b 赋值 给 d 触发拷贝构造 Data method()
{static Data d;return d;
}
Data c = method();//Data c = d   将d  赋值给 c 

析构函数

调用时机: 对象销毁前

  • 生命周期
    • 局部变量:随着所在的函数的调用而生成,随着所在函数的执行完毕而销毁
    • 成员变量:随着所在的对象的创建而生成,随着所在的对象销毁而销毁
    • 全局变量:随着所在的程序启动而生成,随着程序的关闭而销毁
    • 静态局部变量:随着所在函数的第一次调用而生成,随着所在程序的执行完毕而销毁
    • 静态成员变量:随着所在的类的加载而生成,随着所在程序的执行完毕而销毁
    • 静态全局变量:随着所在的程序启动而生成,随着程序的关闭而销毁

堆区开辟的内存

必须手动回收

class Data
{
};
int *method()
{int *num = (int *)calloc(1, 4);char *str = (char *)calloc(50, 1);// Data d;Data *d = new Data();return num;
}
int main()
{int *p = method();
}

野指针与空指针

> 指针存储的地址是随机的  有可能指向 堆区 有可能指向栈区 或者其他区 是不可控的 因为栈区的会自动释放 所以当指向栈区的时候程序不报错 但是这是不可控的	
> 空指针存储的地址是	NULL
注意:对象的成员变量的值默认为 随机数所以 一定注意   拷贝函数的时候不要判断是否不为空并释放因为 成员变量默认是随机数 所以就不是 空的 你一旦释放因为是随机的所以指针就是野指针 释放野指针就会触发重复释放的核心段错误  所以  写的时候 只有 析构的时候需要进行判断 而且要注意继承的情况 
class Data
{
public:int x;char *str;Data() : x(0), str(NULL){}Data(int x, char *str) : x(x){int len = strlen(str) + 1;this->str = (char *)calloc(len, 1);strcpy(this->str, str);}Data(const Data &d){this->x = d.x;int len = strlen(d.str) + 1;this->str = (char *)calloc(len, 1);strcpy(this->str, d.str);}~Data(){if (str != NULL){free(str);str = NULL;}}
};
Data d1;
cout << d1.x << endl;
Data d2(10, "张三");

虚函数与纯虚函数

虚函数:

  • 有函数体,所在的类,可以创建对象,正常继承,子类重写父类虚函数,子类对象转换

    为父类对象后调用该函数执行的子类重写的该函数

  • 纯虚函数:没有函数体,所在的类不能直接创建对象,可以继承,但是子类要么也是抽

    象类,要么重写其所有纯虚函数重写的纯虚函数也是虚函数

虚析构造与纯虚析构

  • 应该释放的是 放父 子也释放

  • 放子 只释放了父 子本身没释放

类模版

class 类名 : public 父类名
{
private:成员变量
public:无参构造函数有参构造函数基本类型 用 =  指针类型 考虑要不要深拷贝 拷贝构造基本类型 用 = 指针类型考虑要不要深拷贝 virtual 析构函数释放深拷贝在堆区的空间get constset 特有函数
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

论 JAVA 集合框架中 接口与类的关系

前言 这是笔者在学习过程中的一篇"备忘录",其目的是能用最EZ最粗鄙的语言口述出 JAVA集合框架中 所有类与接口的关系 本人在不断地学习中,总会混淆集合框架中的类和接口,以及它们的作用关系,虽然不影响我的使用,但是我也不想一直糊涂下去,故而趁知识还没混淆之际,赶…

【练习16】求最小公倍数

链接&#xff1a;求最小公倍数_牛客题霸_牛客网 (nowcoder.com) 题目分析&#xff1a; 要求最小公倍数&#xff0c;要先用辗转相除法求最大公约数。假如有两个数a、b&#xff1a; 最小公倍数a*b / a和b的最大公约数 最大公约数 &#xff08;b, a % b&#xff09;&#xff0c;直…

Redis数据结构之zset

一.zset有序集合 它和集合唯一不同的就是&#xff0c;有序集合中的每一个元素都有一个唯一对应的浮点类型的分数与之关联着&#xff0c;是的有序集合中的元素可以维护有序性。 但是这个有序不适用下标作为排序的依据&#xff0c;而是使用这个分数。就好像排行榜一样&#xff…

Spark MLlib实践指南:从大数据推荐系统到客户流失预测的全流程建模

问题一 背景&#xff1a; 本题目基于用户数据&#xff0c;将据数据切分为训练集和验证集&#xff0c;供建模使用。训练集与测试集切分比例为8:2。 数据说明&#xff1a; capter5_2ml.csv中每列数据分别为userId , movieId , rating , timestamp。 数据&#xff1a; capte…

jboss

一。CVE-2015-7501 1.POC&#xff0c;访问地址 192.168.10.193:8080/invoker/JMXInvokerServlet 返回如下&#xff0c;说明接⼝开放&#xff0c;此接⼝存在反序列化漏洞 2.下载 ysoserial ⼯具进⾏漏洞利⽤ https://github.com/frohoff/ysoserial 将反弹shell进⾏base64编码…

828华为云征文 | 使用Flexus X实例搭建Dubbo-Admin服务

一、Flexus X实例简介 华为云推出的Flexus云服务&#xff0c;作为专为中小企业及开发者设计的新一代云服务产品&#xff0c;以其开箱即用、体验卓越及高性价比而著称。其中的Flexus云服务器X实例&#xff0c;更是针对柔性算力需求量身打造&#xff0c;能够智能适应业务负载变化…

msvcp100.dll丢失怎样修复,总共有6种修复方法

在现代的数字化生活中&#xff0c;电脑已经成为我们工作、学习和娱乐的重要工具。然而&#xff0c;由于各种原因&#xff0c;电脑可能会出现各种问题&#xff0c;其中最常见的就是一些系统文件丢失或损坏。最近&#xff0c;有用户反映他们的电脑出现了“msvcp100.dll丢失”的问…

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第七期]

QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第七期] 第七期介绍&#xff1a;事件订阅之WebSocket方式 目录 QQ频道机器人零基础开发详解(基于QQ官方机器人文档)[第七期]第七期介绍&#xff1a;事件订阅之WebSocket方式 WebSocket方式通用数据结构 Payload长连接维护 O…

LLMs之LCM:《MemLong: Memory-Augmented Retrieval for Long Text Modeling》翻译与解读

LLMs之LCM&#xff1a;《MemLong: Memory-Augmented Retrieval for Long Text Modeling》翻译与解读 导读&#xff1a;MemLong 是一种新颖高效的解决 LLM 长文本处理难题的方法&#xff0c;它通过外部检索器获取历史信息&#xff0c;并将其与模型的内部检索过程相结合&#xff…

Linux C高级day3

一、思维导图 二、练习 #!/bin/bash mkdir ~/dir mkdir ~/dir/dir1 mkdir ~/dir/dir2 cp -r * ~/dir/dir1/ cp -r *.sh ~/dir/dir2/ cd ~/dir/dir2/ tar -cvJf dir2.tar.xz dir2 mv dir2.tar.xz ~/dir/dir1/ cd ~/dir/dir1 tar -xvJf dir2.tar.xz #!/bin/bash head -5 /etc/gr…

高版本JMX Console未授权

1.环境搭建 cd vulhub-master/jboss/CVE-2017-12149 docker-compose up -d 2.访问漏洞地址 nullhttp://47.121.211.205:8080/jmx-console/ 3.远程下载war包 输入远程war包的地址 http://47.121.211.205/shell.war 4.访问上传文件并进行连接 访问上传文件 使用工具进行连…

Jboss 靶场攻略

CVE-2015-7501 步骤一&#xff1a;环境搭建 cd vulhub/jboss/JMXInvokerServlet-deserialization docker-compose up -d docker ps 步骤二&#xff1a;POC&#xff0c;访问地址 http://192.168.10.190:8080/invoker/JMXInvokerServlet 返回如下&#xff0c;说明接⼝开放&…

【Linux进程】进程退出

目录 前言 1. 进程退出的几种情况 2. 进程常见的退出方式 3. 退出码与错误码 4. 进程异常 5. exit与_exit 6. 进程等待 wait与waitpid 获取子进程status 非阻塞等待 前言 进程执行结束退出&#xff0c;就必然需要进行资源回收&#xff0c;子进程由父进程回收&#xff0c…

LampSecurityCTF4 靶机渗透 ( sqlmap ,ssh 参数调整 )

靶机介绍 来自 vulnhub 主机发现 ┌──(kali㉿kali)-[~/testLampSecurityCTF4] └─$ sudo nmap -sn 192.168.50.0/24 [sudo] password for kali: Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-22 10:30 CST Nmap scan report for 192…

自闭症孩子送寄宿学校,给他们成长的机会

在自闭症儿童的教育与康复之路上&#xff0c;选择一种合适的寄宿方式对于孩子的成长至关重要。这不仅关乎到孩子能否获得专业的训练与关怀&#xff0c;还直接影响到他们未来的社交能力、独立生活能力以及心理健康。今天&#xff0c;我们将以广州的星贝育园自闭症儿童寄宿制学校…

【VUE3.0】动手做一套像素风的前端UI组件库---Radio

目录 引言做之前先仔细看看UI设计稿解读一下都有哪些元素&#xff1a;参考下成熟的组件库&#xff0c;看看还需要做什么&#xff1f; 代码编写1. 设计group包裹选项的组件group.vueitem.vue 2. 让group的v-model和item的value联动起来3. 完善一下item的指示器样式4. 补充禁用模…

MAE 模型

masked autoencoders (MAE) 论文地址&#xff1a;https://arxiv.org/abs/2111.06377 代码地址&#xff1a;https://github.com/facebookresearch/mae 模型结构图: 思想&#xff1a;自监督学习&#xff08;Self-Supervised Learning&#xff09;&#xff0c;遮住大部分&…

机器学习(1)sklearn的介绍和六个主要模块、估计器、模型持久化

文章目录 1.sklearn介绍2.sklearn的模块3.监督学习和无监督学习1. 监督学习 (Supervised Learning)例子 2. 无监督学习 (Unsupervised Learning)例子 4.估计器估计器的主要特性和方法包括&#xff1a;估计器的类型&#xff1a;示例&#xff1a;使用 scikit-learn 中的估计器 5.…

恶意windows程序

Lab07-01.exe分析&#xff08;DOS攻击&#xff09; 1.当计算机重启后&#xff0c;这个程序如何确保它继续运行(达到持久化驻留)? 创建Malservice服务实现持久化 先分析sub_401040桉函数 尝试获取名为HGL345互斥量句柄&#xff0c;如果不存在则直接结束流程&#xff1b;如果存…

Zotero(7.0.5)+123云盘同步空间+Z-library=无限存储文献pdf/epub电子书等资料

选择123云盘作为存储介质的原因 原因1&#xff1a; zotero个人免费空间大小&#xff1a;300M&#xff0c;如果zotero云端也保存文献pdf资料则远远不够 原因2&#xff1a; 百度网盘同步文件空间大小&#xff1a;1G123云盘同步文件空间大小&#xff1a;10G 第一台电脑实施步骤…