第三部分 资源管理(条款13-17)
来源:互联网 发布:开源中国app源码下载 编辑:程序博客网 时间:2024/05/18 00:34
条款13 以对象管理资源
class Investment{.........};
假设有个工产函数: Investment* createInvestment();
现在:
void f()
{
Investment* pInv = createInvestment();
....
delete pInv;
}
这个函数看起来是没有什么问题的,但是如果在...部分因为某种原因过早地return了,delete无法执行。那么我们可以把资源放入对象中:
void f()
{
std::auto_ptr<Investment>pInv(createInvestment());
.....
}
其中auto_ptr是一个类指针对象(智能指针),析构函数自动对其对象调用delete
由于auto_ptr被销毁后会自动析构,所以不能够让多个auto_ptr 指向同一个对象。如果那样的话,一个对象会删除一次以上。所以auto_ptr有一个性质:通过copy后他会变成null,而复制所得到的指针取得唯一拥有权。
为了解决这个问题它的替代方法是“引用计数型智慧指针”
void f()
{
....
std::tr1::shared_ptr<Investment> pInv(createInvestment());
....
}
当然这种行为支持正常的复制了
我们需要注意的是无论是auto_ptr还是shared_ptr都不支持delete[ ],所以不能够分配数组
条款14: 在资源管理类中小心copying行为
条款13中的观念都表现在heap-based资源上,他们不适合做资源的管理者,我们需要建立自己的资源管理类
class Lock
{
public:
explicit Lock(Mutex* pm):mutexPtr(pm)
{ lock(mutexPtr); }
~Lock()
{ unlock(mutexPtr); }
private:
Mutex* mutexPtr;
};
客户用法:
Mutex m;
...
{
Lock m1(&m);//加锁
....
} //自动释放锁
现在 Lock m1(&m);
Lock m2(m1); //复制会发生什么事情?
大多的做法:
第一是 禁止复制 class Lock:private Uncopyable{............};
第二 使用share_ptr 但是不幸的是这个是在指针计数为0时删除,我们要的不是删除是解除锁。针对这种情况shared_ptr提供了一种指定删除器的方法:
class Lock
{
public :
explicit Lock(Mutex* pm):mutexPtr(pm,unlock) //这里使用unlock函数为删除器,当计数为0的时候直接调用这个函数
{lock(mutexPtr.get()) ;}
private:
std::tr1::shared_ptr<Mutex> mutexPtr;
};
条款15: 在资源管理类中提供对原始资源的访问
条款13中 std::tr1::shared_ptr<Investment> pInv(createInvestment());
现在我们有个函数:
int daysHeld(const Investment* pi);
如果直接传入pInv肯定会是错误的,有两种做法可以达到目的
一个是auto和shared都提供了get函数,所以可以这么做: int days = daysHeld(pInv.get());
另外利用智能指针对operator-> 和operator*重载
class Investment
{
public:
bool isTaxFree() const;
....
};
Investment* createInvestment();
std::tr1::shared_ptr<Investment> p1(createInvestment());
bool taxable1 = !(p1->isTaxFree());
....
std::auto_ptr<Investment> p2 (createInvestment());
bool taxable2 = !((*p2).isTaxFree());
请记住:
1.API一般都要求访问原始资源,所以我们管理资源应该提供访问原始资源的方法
2.对原始资源的访问可以通过显示转换或者隐式转换,一般来说后者不够安全,但是对客户比较方便。
条款16:成对出现new和delete
这里是说new一个数组,也要delete一个数组。new一个对象 也delete一个对象
条款17:以独立语句将newed对象植入智能指针
假设我们这里有个函数
int priority();
void processWidget(std::tr1::shared_ptr<Widget>pw,int priority);
这么调用肯定是错误的:processWidget(new Widget,priority());理由很明显了new这个地方出错
那么我们考虑这样: processWidget(std::tr1::shared_ptr<Widget>(new Widget),priority());这么做可能导致泄漏资源。processWidget(std::tr1::shared_ptr<Widget>(new Widget)的执行首先是new 再构造shared_ptr对象,那么整个函数有三个步骤,前面两个加上一个priority(); 在C++里面执行的步骤是不确定的,他们可能这么做:
1.new
2.priority()
3.shared_ptr...
如果第二个步骤出错,资源泄漏了
所以改进的方法这么做:
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw,priority());
- 第三部分 资源管理(条款13-17)
- 3 资源管理 条款13~条款17
- 《Effective C++》资源管理:条款16-条款17
- 《Effective C++》资源管理:条款13-条款15
- Effective C++读书笔记 第三部分 资源管理
- Effective C++ 笔记 第三部分 资源管理
- 《Effective C++》资源管理:条款20-条款21
- 《Effective C++》资源管理:条款22-条款24
- 《Effective C++》资源管理:条款26-条款27
- 第三章信息系统资源管理
- 信息资源管理 第三章
- 第三章 资源管理
- 第三章 资源管理
- 第三章 资源管理
- 条款13-15(资源管理,其实就是讲的智能指针)
- effective C++ 条款13 to 条款17
- 【Effective C++】读书笔记 条款13~条款17
- CocoaPods进行第三方资源管理
- ICMP报文的类型说明
- lseek
- 未来技术展望---无线充电技术
- dedecms 5.7 文章不能上传图片的解决方法(Upload filetype not allow)
- 强烈建议CSDN加上软件测试模块
- 第三部分 资源管理(条款13-17)
- VC环境下的多线程API
- 对运算符号进行重载,进行复数运算
- Android Mms 专题——PDU介绍
- wordpress多站点(MU)用二级域名(SUBDOMAIN)的单点登录(SSO)问题
- float与int间的相互转换问题
- linux下打开服务
- iPhone开发资料收集
- Android Mms专题——对话与联系人的关联