C++ 异常类型及其生命周期

本文深入探讨了C++中异常抛出与捕获机制,特别是针对自定义对象类型的处理方式,包括析构函数的作用、对象指针与引用的捕获区别,以及不同抛出方式对生命周期的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个悬而未决的问题,看了代码值得探讨一下~~

针对最后问题的解答:不要认为析构函数调用后,就真的吃掉了你的内存,析构函数只不过告诉你这部分内存现在不再是某一个对象独占的了,你有权访问它,但其它人也有权修改它,在别人没修改之前,访问得到的值依然不变而已。

如果捕获方式使用对象指针的类型:那么

对于throw &test_class()这种异常的抛出方式,其生命周期不会延续到异常的处理阶段,抛出异常后即会被析构,使用对象指针的方式捕获到的不过是一个野指针,虽然依旧可以访问,但风险非常大(野指针)(解释在上面)。

对于throw new test_class(),那么就需要new在堆上分配内存,手动进行内存的释放(有一点点小麻烦:底层函数new,上层函数delete)

综上,使用对象指针的类型进行异常对象的捕获非常不合适,建议使用引用的方式进行捕获

#include<iostream>
using namespace std;

class test_class
{
public:
	test_class() {
		cout << "默认构造函数" << endl;
	}
	test_class(const test_class& obj)
	{
		cout << "拷贝构造函数" << endl;
	}
	~test_class()
	{
		cout << "析构函数" << endl;
	}
	int m = 128;
};

//交换字符串
void swap_string(char* src, char* des)
{
	if (src == NULL)
	{
		throw 1;
	}
	if (des == NULL)
	{
		throw "目标字符串为空";
	}
	if (*src == 'a')
	{
		//这里抛出类类型比较特殊,注意写法,类名直接加括号
		//throw test_class();
		//想要不进行复制操作,可以用其引用或者指针类型进行捕捉,指针类型的捕捉可以用new的
		throw &test_class();
		//throw new test_class();
	}
}

int main()
{
	char *src = "abcdefg";
	char des[100];
	try
	{
		swap_string(src, des);
	}
	//方式1:类型捕获
	catch (int)
	{
		cout << "类型捕获,抛出的异常对象不可用" << endl;
	}
	//方式2:异常对象捕获,依据的是类型的严格匹配(方式1和方式2如果在类型上一致则不能共存)
	//error C2312: “int”: 由“int”在行 47 上捕获
	/*catch (int a)
	{
		cout << "异常对象捕获,依据的是类型的严格匹配 捕获对象为:" <<a<< endl;
	}*/
	//异常类型1:捕获指针类型(对应抛出字符串时的情况)
	catch (char* a)
	{
		cout << "捕获指针类型" << a << endl;
	}
	//异常类型2:捕获引用类型
	catch (char& a)
	{
		cout << "捕获引用类型" << a << endl;
	}
	//异常类型3:捕获自定义对象类型(此步骤会调用拷贝构造函数进行对象的拷贝)
	catch (test_class a)
	{
		cout << "捕获自定义对象类型" << endl;
	}
	//异常类型4:捕获自定义对象引用类型(对象的引用 和对象的本身不能共存)
	// error C2315: “test_class &”: 引用由“test_class”在行 67 上捕获
	/*catch (test_class& a)
	{
		cout << "捕获指针类型" << endl;
	}*/
	//异常类型5:捕获自定义对象指针类型
	catch (test_class* a)//(此步骤捕获对象的地址或者是new出来对象的指针,针对new需要手动delete,所以一般不使用它)
	{
		cout << "捕获指针类型" << endl;
		cout << a->m << endl;
	}
	//这里可能是最新版本的优化问题,在使用 &test_class()进行指针捕获时,运行即可看出其构造函数与析构函数已经被执行了
	//这就意味着传过来的指针是一个野指针了,但是我尝试一下调用a->m仍能得到正确的值,不知道是不是编译器优化的问题
	//当做悬而未决的问题吧
	catch (...)
	{
		cout << "其他类型异常" << endl;
	}
	system("pause");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MISAYAONE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值