Effective C++第三章-资源管理-1
2017-06-30 14:38
351 查看
C++的资源:
动态分配内存文件描述器
数据库连接
网络sockets
互斥锁
图形界面中的字型和笔刷
以对象管理资源(又称为资源取得时机便是初始化时机,resource acquisition is initialization,RAII)
单纯依靠调用端执行delete语句是行不通的:一般调用端函数使用了函数(Create函数)返回的对象后,有责任删除之。但在以下情况下可能使得调用端函数来不及删除
一个过早的return语句
一个存在continue和goto语句的循环
某个语句抛出异常
为确保Create函数返回的资源总是被释放,我们需要将资源放进对象内,当控制流离开调用端函数,该对象的析构函数会自动释放资源
例1:auto_ptr
Header: < memory >
Namespace: std
是一个类指针对象,也就是智能指针,其析构函数自动对其所指对象调用delete
void f() { std::auto_ptr<Investment> pInv(createInvestment()); //利用create函数获得资源后立即放进对象pInv ... }//经由auto_ptr的析构函数自动删除pInv
PS:对象被删除一次以上,会使程序出现“未定义行为”
诡异的复制行为:若通过copy构造函数或copy assignment操作符复制它们,它们会变成null,而复制所得的指针将取得资源的唯一拥有权,因此,受auto_ptr管理的资源必须绝对没有一个以上的auto_ptr同时指向它。
std::auto_ptr<Investment> pInv1(createInvestment()); std::auto_ptr<Investment> pInv2(pInv1);//现在pinv2指向对象,pInv1被设为NULL pInv1 = pInv2; //现在pInv1指向对象,pInv2被设为NULL
例2:引用计数型智慧指针(reference-counting smart pointer,RCSP)shared_ptr
Header: < memory >
Namespace: std::tr1
也是智能指针,持续追踪共有多少对象指向某笔资源,并在无人指向它时自动删除该资源。
void f()
{
std::tr1::shared_ptr pInv(createInvestment());
//利用create函数获得资源后立即放进对象pInv,shared_ptr是一个RCSP
…
}//经由shared_ptr的析构函数自动删除pInv
RCSP无法打破环状引用(例如两个其实已经没被使用的对象彼此互指,因而好像处于“被使用”状态)。
缺省行为是“当引用次数为0时删除其所指”,std::tr1::shared_ptr也允许指定“删除器”,是一个函数或函数对象,当引用次数为0时便被调用,删除器对std::tr1::shared_ptr构造函数而言是可有可无的地儿参数(此机能不存在于auto_ptr,它总是将其指针删除)
class Lock{ public: explicit Lock(Mutex* pm):mutexPtr(pm,unlock){}//以unlock函数为删除器 private: std::tr1::shared_ptr<Mutex> mutexPtr; };
复制
std::tr1::shared_ptr<Investment> pInv1(createInvestment()); std::tr1::shared_ptr<Investment> pInv2(pInv1);//pinv2,pInv1指向同一对象 pInv1 = pInv2; //pinv2,pInv1指向同一对象
在auto_ptr和shared_ptr的析构函数内做delete而不是delete[],因此虽然可以通过编译,在动态分配而得的array身上使用是馊主意。
在复制资源管理对象时,进行的是“深度拷贝”
对于非heap-based资源,像auto_ptr和tr1::shared_ptr智能指针往往不适合作为资源掌管者
PS : TR1(Technical Report 1)是一份规范,描述加入C++标准程序的诸多新技能大多数TR1机能是以Boost的工作为基础的。TR组件位于std::tr1命名空间中。大多数TR1机能是以Boost的工作为基础的。TR组件位于std::tr1命名空间中。
在资源管理类中应提供对原始资源的访问
举例:std::tr1::shared_ptr<Investment> pInv(createInvestment()); ... int fun(const Investment* pi); ... int x = fun(pInv);//错误,所需参数是Investment*指针,但是传递的是tr1::shared_ptr<Investment>对象
解决方法:
显式转换(比较安全)
tr1::shared_ptr和auto_ptr都提供一个get成员函数执行显式转换。也就是它会返回智能指针内部的原始指针(的复件):
int x = fun(pInv.get());
隐式转换(对客户比较方便)
同所有智能指针一样,tr1::shared_ptr和auto_ptr也重载指针取值操作符(operator->和operator*),它们允许隐式转换至底部原始指针:
class Investment{ public: bool isfun() const; ... }; Investment* createInvestment(); std::tr1::shared_ptr<Investment> pi1(createInvestment()); bool isf1 = !(pi1->isfun()); ... std::tr1::shared_ptr<Investment> pi1(createInvestment()); bool isf1 = !((*pi1).isfun());
提供隐式转换函数
相关链接
相关文章推荐
- Effective C++——》条款14:在资源管理中小心copying行为
- Effective C++ Item 13-以对象管理资源
- Effective C++ 条款13 以对象管理资源
- effective c++ item13:使用对象管理资源
- Effective C++ rule 14 在资源管理对象中处理好copy行为
- Effective C++ —— 资源管理(三)
- C++内存管理------>以对象管理资源(Effective C++)
- Effective Modern C++ 条款18 用std::unique_ptr管理独占所有权的资源
- 读书笔记_Effective_C++_条款十三:以对象管理资源
- <<Effective C++>>读书笔记3: 资源管理
- 读书笔记 effective c++ Item 13 用对象来管理资源
- 读书笔记 effective c++ Item 13 用对象来管理资源
- Effective C++ rule 13 用对象管理资源
- Effective Modern C++ 条款19 用std::shared_ptr管理共享所有权的资源
- Effective C++ Item 14-在资源管理中小心的copying行为
- Effective C++ Item 13 以对象管理资源
- Effective C++——》条款13:以对象管理资源
- Effective C++ — 资源管理
- more-effective-c++ 序列2 异常(第9节,如何利用局部对象管理资源)的测试示例
- <Effective C++> (Item 13-15): 以对象管理资源