C++必知必会:RAII惯用法

使用RAII惯用法

RAII(Resource Acquisition Is Initialization, 资源获取即初始化)指资源在我们拿到的时候就已经初始化,一旦不需要该资源,就可以自动释放该资源。

对于C++来说,资源在构造函数中初始化(可以在构造函数中调用单独的初始化函数),在析构函数中释放或清理。常见的情形就是再函数调用过程中创建C++对象时分配资源,在C++对象出了作用域时将其自动清理和释放。

分配堆内存示例

如下代码,heapObj出了作用域该程序就会自动调用析构函数释放堆内存

// 定义HeapObjectWrapper RAII 对象
class HeapObjectWrapper
{
public:
	HeapObjectWrapper(int size)
	{
		m_p = new char[size];
	}

	~HeapObjectWrapper()
	{
		delete[] m_p;
		m_p = NULL;
	}

private:
	char* m_p;
};

// 使用 HeapObjectWrapper RAII对象
int main(void)
{
	HeapObjectWrapper heapObj(1024);
	if (测试操作) {}

	return 0;
}

对多线程锁的获取和释放

在日常写的代码里,为了避免死锁,通常会在每个可能退出的分支上都释放锁,随着逻辑越来越复杂,可能会在某个可能退出的分支上忘记释放锁。

RAII可以解决这个问题:将锁包裹成一个对象,在构造函数中获取锁,在析构函数中释放锁。

伪代码示例:

class SomeLockGuard
{
public:
	SomelockGuard()
	{
		// 加锁
		m_lock.lock();
	}

	~SomeLockGuard()
	{
		// 解锁
		m_lock.unlock();
	}
private:
	SomeLock m_lock;
};

int main(void)
{
	SomeLockGuard lockWrapper;
	if (条件1)
	{
		if (条件2) {
			//操作1
			return;
		}
		else {
			// 操作2
			return;
		}
	}

	if (条件3)
	{
		// 操作3
		return;
	}
}

使用RAII惯用法之后,我们就再也不必在每个函数出口处都加上释放锁的代码了,因为在函数调用结束后会自动释放锁。

小结

资源泄漏和死锁等问题具有非常强的隐蔽性,如果在生产环境中出现这些问题,则难以复现,排查和定位问题。
只要理解并熟练使用RAII惯用法不仅能让我们的代码更加简洁和模块化,也能让我们在开发阶段避免一部分资源泄漏和死锁问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_索伦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值