C++ 资源管理(RAII)

版权声明:转载请说明来源 https://blog.csdn.net/weixin_39640298/article/details/88878041

1、概述

所谓资源,就是程序员从操作系统中获取的硬件资源,我们申请了资源,使用完毕之后要还给系统。C++最常使用的是内存资源,其它还包括文件描述符、互斥锁、图形界面中的字型和笔刷、数据库连接、以及网络socket等。

尝试在任何运用情况下对资源的正确回收,是件困难的事情,尤其是你考虑到异常、函数内多重回传路径、程序维护员改动软件却没能充分理解随之而来的冲击。高能的程序员就指定了这样一条规则,来进行资源的管理。

RAII(Resource Aquisition Is Initialization),也称为 “资源获取时机就是初始化时机”利用了C++的语言机制:对象在超出作用域的时候其析构函数会被自动调用。在对象构造时其所需的资源便在构造函数中进行初始化,而对象析构的时候则释放这些资源。

而使用最多的可能就是 智能指针互斥锁的使用了。如下:

void func()
{
	std::shared_ptr<int> pint(new int(10));	//这里使用了共享指针,里面有计数功能,等数量为0则析构
	......	
	......		//函数最后不用对new出的数据进行释放,堆栈会自动调用析构函数,进行释放
}

std::mutex mutex;	//互斥锁
void func2()
{
	std::unique_lock<std::mutex> lock(mutex);	//对互斥锁进行加锁
	......
	......		//不需要进行解锁,堆栈调用析构函数,在析构函数中进行解锁
}

C++ 库给我们提供了一些 RAII 类,但有时往往不适合现有系统,你需要建立自己的资源管理类。

需要注意的是:对内存的资源管理 RAII 对象,析构函数中一般使用 delete 关键字,所以RAII 对象最好不要管理数组。

2、书写一个RAII类的原则

1、最重要的原则是:资源在对象构造期间初始,在析构期间进行释放。

2、许多时候允许 RAII 对象被复制并不合理。如果不合理则应该对RAII的拷贝操作进行禁止。

3、对引用计数法的 RAII 对象,我们需要在它的最有一个使用者用完之后进行销毁。复制对象时,应该将资源的被引用数递增。如:shared_ptr

4、申请的资源我们一定是希望使用这个资源,所以RAII 类要提供对原始资源访问。

5、对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换比较安全,但隐式转换对用户比较方便。

例子如下:

class Resource{}; 

class RAII
{ 
public: 
    RAII(Resource* aResource):r_(aResource){} 	//获取资源 
    ~RAII() {delete r_;} 						//释放资源 
    Resource* get()    {return r_ ;} 			//访问资源 
	RAII(const RAII& that) = delete;			//禁止拷贝
	RAII& opeator=(const RAII& that) = delete;	//禁止赋值
private: 
    Resource* r_; 
};  

感谢大家,我是假装很努力的YoungYangD(小羊)

参考资料:
《Effective C++》

猜你喜欢

转载自blog.csdn.net/weixin_39640298/article/details/88878041