C++_22_异常

news2024/11/15 4:07:23

文章目录

  • 异常
    • 概念:
    • **抛出异常:**
        • 关键字:
    • **捕获异常:**
    • **栈解旋:**
    • **异常的接口声明:**
    • **异常对象的生命周期:**
      • 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 const
        set 特有函数
}

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

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

相关文章

Xilinx系FPGA学习笔记(八)FPGA与红外遥控

系列文章目录 文章目录 系列文章目录红外通信简单介绍红外协议分析 FPGA实现红外通信 红外通信 简单介绍 利用红外线来传送&#xff0c;不干扰其他电器设备工作&#xff0c;也不会影响周边环境&#xff0c;若对发射信号进行编码&#xff0c;可实现多路红外遥控功能。 红外遥控…

全面介绍 CSS 属性值计算 —— 掌握它就了解大部分 CSS

CSS 的核心之一就在此&#xff0c;直接影响我们开发中的调试和布局&#xff01;&#xff01;&#xff01; 举个 &#x1f330;&#xff1a;页面上存在一个 h1 元素&#xff0c;不设置任何样式&#xff0c;但是当我们点开 computed 查看&#xff0c;几乎 MDN 上的 CSS 属性都存…

C++高精度计时方法总结(测试函数运行时间)

文章目录 一、clock()函数——毫妙级二、GetTickCount()函数&#xff08;精度16ms左右&#xff09;——毫妙级三、高精度时控函数QueryPerformanceCounter()——微妙级四、高精度计时chrono函数——纳妙级五、几种计时比较六、linux下的计时函数gettimeofday()-未测试参考文献 …

C语言6大常用标准库 -- 4.<math.h>

目录 引言 4. C标准库--math.h 4.1 简介 4.2 库变量 4.3 库宏 4.4 库函数 4.5 常用的数学常量 &#x1f308;你好呀&#xff01;我是 程序猿 &#x1f30c; 2024感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&#xff0c;共同成长&…

《他们的奇妙时光》圆满收官,葛秋谷新型霸总获好评

9月21日&#xff0c;由王枫、张开法执导&#xff0c;周洁琼、葛秋谷领衔主演的奇幻爱情题材都市喜剧《他们的奇妙时光》圆满收官。该剧讲述了意外被游戏角色刑天附体的设计师宋灵灵&#xff0c;为修复游戏漏洞&#xff0c;被迫与能压制刑天的甲方总裁萧然同居&#xff0c;两人在…

LDR6020在索尼PS5 VR2适配器中的应用技术方案探讨

随着虚拟现实&#xff08;VR&#xff09;技术的日益成熟&#xff0c;索尼PlayStation VR2&#xff08;简称PS VR2&#xff09;作为新一代VR设备&#xff0c;凭借其出色的性能和沉浸式体验&#xff0c;成为了游戏界的焦点。为了进一步扩大PS VR2的应用范围&#xff0c;索尼推出了…

深度学习02-pytorch-01-张量的创建

深度学习 pytorch 框架 是目前最热门的。 深度学习 pytorch 框架相当于 机器学习阶段的 numpy sklearn 它将数据封装成张量(Tensor)来进行处理&#xff0c;其实就是数组。也就是numpy 里面的 ndarray . pip install torch1.10.0 -i https://pypi.tuna.tsinghua.edu.cn/simp…

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…

分布式网络存储技术是什么?分布式存储技术有哪些

分布式储存是指将数据分散存储在多个节点上的一种技术。但是你们知道分布式网络存储技术是什么&#xff1f;相比传统的集中式存储&#xff0c;分布式储存具有更高的可靠性和可用性。分布式网络存储是一种将数据分散存储在多个节点或服务器上的架构。 分布式网络存储技术是什么&…

开源 AI 智能名片 S2B2C 商城小程序与营销工具的快速迭代

摘要&#xff1a;本文以开源 AI 智能名片 S2B2C 商城小程序为研究对象&#xff0c;探讨在营销工具快速迭代的背景下&#xff0c;该小程序如何借鉴以拼多多为代表的“小程序拼团”、以蘑菇街为代表的“小程序直播”、以花点时间为代表的“小程序按月订花”等经典案例&#xff0c…

springboot注册和注入组件方式概览

IoC&#xff1a;Inversion of Control&#xff08;控制反转&#xff09; 控制&#xff1a;资源的控制权&#xff08;资源的创建、获取、销毁等&#xff09; 反转&#xff1a;和传统的方式不一样了 DI &#xff1a;Dependency Injection&#xff08;依赖注入&#xff09; 依赖&…

【HTTPS】对称加密和非对称加密

HTTPS 是什么 HTTPS 是在 HTTP 的基础上&#xff0c;引入了一个加密层&#xff08;SSL&#xff09;。HTTP 是明文传输的&#xff08;不安全&#xff09; 当下所见到的大部分网站都是 HTTPS 的&#xff0c;这都是拜“运营商劫持”所赐 运营商劫持 下载⼀个“天天动听“&…

剖析枚举类型的使用与优点

枚举类型顾名思义——就是把所有的值一一列举出来 列如星期 把每一项都列举出来就是枚举 这些可能取值都是有值的&#xff0c;默认从0开始&#xff0c;依次递增1&#xff0c;当然在声明枚举类型的时候也可以赋初值&#xff0c; 要是在某一项赋初值之后&#xff0c;后面的就会…

客户转化预测以及关键因素识别_支持向量机与相关性分析

数据入口&#xff1a;数字营销转化数据集 - Heywhale.com 数据集记录了客户与数字营销活动的互动情况。它涵盖了人口统计数据、营销特定指标、客户参与度指标以及历史购买数据&#xff0c;为数字营销领域的预测建模和分析提供了丰富的信息。 数据说明&#xff1a; 字段说明Cu…

JavaEE: 创造无限连接——网络编程中的套接字

文章目录 Socket套接字TCP和UDP的区别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP api的使用UDPDatagramSocketDatagramPacketInetSocketAddress练习 TCPServerSocketSocket练习 Socket套接字 Socket是计算机网络中的一种通信机制&#xff0…

Clion使用vcpkg管理C/C++包

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Clion安装vcpkg二、使用步骤1.切换到清单模式2.开始安装包 三、测试代码总结 前言 Linux上的库基本都可以通过apt或yum等包管理工具来在线安装包&#xff…

cgroup基本原理与使用

Linux cgroups是Linux内核中的一项强大功能&#xff0c;允许用户对进程进行**资源限制、优先级控制、监控和隔离。它主要用于管理和控制计算资源的分配&#xff0c;特别是在容器技术&#xff08;如 Docker 和 LXC&#xff09;中得到了广泛应用。 1. Cgroups的基本概念和原理 …

Qwen-2.5 + ClaudeDev + Aider:这套免费的AI编程工具链,简直太棒了!

Qwen-2.5 ClaudeDev Aider&#xff1a;这套免费的AI编程工具链&#xff0c;简直太棒了&#xff01; 原创 Aitrainee AI进修生 &#x1f379; Insight Daily &#x1faba; Aitrainee | 公众号&#xff1a;AI进修生 Hi&#xff0c;这里是Aitrainee&#xff0c;欢迎阅读本…

AI字幕翻译器行业分析:前五大厂商占有大约29.5%的市场份额

AI 字幕翻译器正在彻底改变我们使用不同语言消费媒体的方式&#xff0c;使内容可以普遍访问。这些先进的技术利用机器学习和自然语言处理&#xff0c;将口语对话实时翻译成字幕。这一功能不仅打破了语言障碍&#xff0c;提升了观众的体验&#xff0c;而且还使内容创作者能够毫不…

比 Kimi 更强!用 Claude 仿写头条文章,轻松过原创(附完整指令)

最近&#xff0c;我有个做头条号的朋友跟我吐槽&#xff0c;说每天都要更新内容&#xff0c;经常写文章写到半夜&#xff0c;他已经快撑不住了。我听完实在有点不忍心&#xff0c;就告诉他&#xff0c;其实可以用 AI 来帮忙写头条文章。 朋友一脸怀疑&#xff0c;说“怎么可能&…