【C++杂记】C++构造函数失败怎么办,智能指针+异常处理防止内存泄漏

本文探讨了C++构造函数失败后的处理方式及析构函数的行为,并提供了避免构造函数中出现异常的最佳实践。同时介绍了如何利用智能指针来防止内存泄漏。

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

概述

C++构造函数失败后,其对应的析构函数会被自动调用吗?
答案是不会。

能在构造函数中抛出异常,然后在外面捕获吗?
可以,但不建议这样做。C++之父和herb sutter这样的最顶级专家建议不要把容易出错的代码放在构造函数中,当然如果非要在构造函数做一些容易失败的事,那就在构造里throw异常吧。另外对于析构函数,Herb Sutter在Exceptional c++ 中也说过说:“永远都不要写能够抛出异常的析构函数” [1]。

  所以综上,我们写代码时,还是最好不要把易出错的代码写在构造函数里了,我们加个init函数,构造成功后再init,与init对应的还要有个exit函数。

代码示例1:抛出异常后,delete将不不被执行,将造成内存泄漏。

#include <iostream>

void remodel(std::string & str)
{
	std::string * ps = new std::string(str);
	if (true)
		throw "test exception";
	str = *ps;
	delete ps;
	return;
}

void main()
{
	remodel(std::string("abcde"));
}

智能指针和异常处理

我们可以使用智能指针和异常处理来防止内存泄漏。

#include <iostream>  //[2]
#include <string>
#include <memory>

class report
{
private:
	std::string str;
public:
	report(const std::string s) : str(s) {
		std::cout << "Object created.\n";
	}
	~report() {
		std::cout << "Object deleted.\n";
	}
	void comment() const {
		std::cout << str << "\n";
		throw "test exception";
	}
};

int main()
{
	{
		report *ps = NULL;
		try
		{
			ps = new report("using auto ptr");
			ps->comment();
		}
		catch (...)
		{
			std::cout << "test" << std::endl;

			if (ps)
			{
				delete ps;
				ps = NULL;
			}
		}
	}

	{
		std::auto_ptr<report> ps(new report("using auto ptr"));
		try
		{
			ps->comment();
		}
		catch(...)
		{
			std::cout << "test" << std::endl;
		}
	}

#if 0
	{
		std::shared_ptr<report> ps(new report("using shared ptr"));
		ps->comment();
	}

	{
		std::unique_ptr<report> ps(new report("using unique ptr"));
		ps->comment();
	}
#endif
	return 0;
}

参考文献

[1] C++中构造函数是没有返回值的,那么该如何处理构造函数中可能的错误
[2] C++智能指针简单剖析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值