条款14:在资源管理类中小心coping行为

原创 2014年05月28日 19:36:21
条款14:在资源管理类中小心coping行为
    在前一个条款,我们提出了RAII(资源获得即是初始化)技术,通过“对象管理资源”达到防止资源泄露,对于通过堆分配的内存,可以借助指针指针实现,但系统中有很多资源不是堆分配:文件句柄,锁,网络套接字。这些资源就需要自己实现对象来管理。
看一个简单的实现互斥锁资源对象管理
class Mutex{};
void lock(Mutex* mutex) {}  //锁住资源
void unlock(Mutex* mutex) {} //释放资源

class MyLock
{
public:
	explicit MyLock(Mutex *mutex) :m_mutex(mutex)
	{
		lock(m_mutex);
	}

	~MyLock() {unlock(m_mutex);}
private:
	Mutex *m_mutex;
};
调用
void process()
{
	Mutex mutex;
	MyLock mylock(&mutex);
	//process
} //离开作用域,mylock执行析构函数,释放mutex
管理对象被复制了,会出现什么情况?
void process()
{
	Mutex mutex;
	MyLock mylock(&mutex);
	MyLock mylock2(mylock);  //调用默认拷贝构造函数,指向同一个资源
	//process
} //离开作用域,mylock和mylock2执行析构函数,释放mutex两次
如何解决RAII对象被复制的情况呢?
①禁止复制;可以通过条款6的方法禁止类对象复制
class MyLock : private Uncopyable {};
②对底层使用“引用计数法”
   使用shared_ptr成员变量,指向需要管理的资源,当引用计数为0时则delete掉资源,但非堆分配内存是不能delete操作,只需要释放,为此,shared_ptr提供一种方法,即删除器,在引用计数为0时执行
class Mutex{};
void lock(Mutex* mutex) {}  //锁住资源
void unlock(Mutex* mutex) {} //释放资源

class MyLock
{
public:
	explicit MyLock(Mutex *mutex) :m_mutexPtr(mutex, unlock)
	{
		lock(m_mutexPtr.get());
	}

	//~MyLock() {unlock(m_mutex);} //不用再定义析构函数,直接通过m_mutexPtr删除器释放资源
private:
	std::tr1::shared_ptr<Mutex> m_mutexPtr;

};
调用
void process()
{
	Mutex mutex;
	MyLock mylock(&mutex);   //m_mutexPtr引用计数为2
	MyLock mylock2(mylock);  //调用默认拷贝构造函数,指向同一个资源,m_mutexPtr引用计数为2
	//process

} //离开作用域,成员对象mylock和mylock2的智能指针对象都执行析构函数且引用计数减为0,则调用删除器unlock()函数解除锁
③复制底部资源
    有些时候可以对某些资源进行多份拷贝,如常用的string类,实现方法是前面说过的深拷贝
④转移底部资源的拥有权。
    前面说过的auto_ptr就是采用这种技术.

记住
 ①复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为.
 ②普遍而常见的RAII class copying行为是:抑制copying、施行引用计数法.不过其它行为也都可能被实现.


条款14 在资源管理类中小心coping 行为

#include #include using namespace std; class Mutex{ }; void lock(Mutex*pm){ cout
  • sbfksmq
  • sbfksmq
  • 2015年09月05日 00:56
  • 232

Effective C++(14) 在资源管理类中小心copying行为

问题聚焦: 上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的。 这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?...
  • zs634134578
  • zs634134578
  • 2014年01月23日 09:29
  • 1261

《Effect C++》学习------条款14:在资源管理类中小心coping行为

在前一个条款,我们提出了RAII(资源获得即是初始化)技术,通过“对象管理资源”达到防止资源泄露,对于通过堆分配的内存,可以借助指针指针实现,但系统中有很多资源不是堆分配:文件句柄,锁,网络套接字。这...
  • qq_19528953
  • qq_19528953
  • 2016年09月18日 16:40
  • 87

条款14 在资源管理类中小心copying行为

总结: 拷贝RAII 对象必须一并拷贝它所管理的资源,所以资源的拷贝行为决定了 RAII 对象的拷贝行为。 普通的 RAII 类的拷贝行为是:阻止拷贝、引用计数,但其它行为也是有可能的...
  • u013074465
  • u013074465
  • 2015年03月11日 21:17
  • 1042

读书笔记《Effective C++》条款14:在资源管理类中小心copying行为

条款13导入这样的观念:“资源取得时机便是初始化时机(RAII)”,并以此作为“资源管理类”的脊柱,也描述了auto_ptr和shared_ptr如何将这个观念表现在heap-based资源上。然而并...
  • u014558668
  • u014558668
  • 2017年05月08日 23:46
  • 82

以对象管理资源、在资源管理类中小心coping行为、在资源管理类中提供对原始资源的访问

在系统中,资源是有限的,一旦用完必须归还给系统,否则可能会造成资源耗尽或其他问题。例如,动态分配的内存如果用完不释放会造成内存泄漏。 这里说的资源不仅仅是指内存,还包括其他,例如文件描述符、网络...
  • ouyangjinbin
  • ouyangjinbin
  • 2016年04月10日 22:33
  • 186

精通C++资源管理-在资源管理类中小心coping行为

(1)复制RAII对象必须一并复制它所管理的资源,所以资源的复制行为决定RAII对象的复制行为。 (2)普遍而常见的RAII类复制行为是:抑制复制、施行引用计数法。不过其他行为也都可能被实现。 ...
  • DracoWYL
  • DracoWYL
  • 2016年07月21日 16:43
  • 211

C++之在资源管理类中小心copying行为(14)---《Effective C++》

转载:http://www.cnblogs.com/hustcser/p/4103527.html条款14:在资源管理类中小心copying行为 ———————– 第一节 条...
  • u014038273
  • u014038273
  • 2017年07月20日 19:53
  • 205

Effective C++ 学记之14 在资源管理类中 小心 copying行为

复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。 普遍而常见的RAII class copying行为是:抑制copying、施...
  • peace_apple
  • peace_apple
  • 2013年05月09日 14:31
  • 516

Effective C++ Item 14 在资源管理类中小心copying行为

经验:复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。 普遍而常见的RAII classcopying行为是:抑制copying,施行引用...
  • zhsenl
  • zhsenl
  • 2014年05月24日 22:28
  • 423
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:条款14:在资源管理类中小心coping行为
举报原因:
原因补充:

(最多只允许输入30个字)