欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

《Effective C++》读书笔记 资源管理

程序员文章站 2022-05-28 22:41:54
C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等。不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统。 一个很好的做法是以对象管理资源。把资源放进对象内,我们便可依赖C++的析构函数自动调用机制确保资源被释放,这样便不会发生资源泄露的问题。一 ......

C++程序中最常用的资源包括动态分配的内存,文件描述器,互斥锁,数据库连接,网络socket等等。不论哪种资源,重要的是,当你不再使用他时,必须将他归还给系统。

一个很好的做法是以对象管理资源。把资源放进对象内,我们便可依赖C++的析构函数自动调用机制确保资源被释放,这样便不会发生资源泄露的问题。一个实现的方法是,以智能指针封装资源,由于atuo_ptr缺陷太多,已经基本被废弃,建议使用shared_ptr。下面看一个使用shared_ptr的具体实现

void f(){    shared_ptr<Investment> pInv(createInvestment());//工厂函数返回的对象初始化资源,再用shared_ptr封装他}

shared_ptr的一个特性是其提供了引用计数,每当其管理对象被指向便会+1,在无人指向它时自动删除该资源,并且支持copy操作。因为可以很方便的通过它进行内存管理,不用担心资源泄露。

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

一般情况下,对资源的复制行为是不会允许的,比如互斥锁,你不会想要把一个互斥器对象复制的,对吧?所以如果你的资源对象不适合被复制,你应该禁止复制这种行为:把copying操作声明为private,然后继承它,就像下面这样

class Lock:private Uncopyable{   ...};

或者如果你确实有需求复制资源,例如你非得复制互斥器,那就使用前面介绍的shared_ptr吧,但是shared_ptr有一个不幸的特性,当引用次数为0时删除其所指物,不过类似于C++标准库里的其他部件,shared_ptr允许你定制自己的删除器,shared_ptr有一个重载类型接受第二个参数。

Class Lock{public:    explicit Lock(Mutex* pm):mutexPtr(pm,unlock)//第二个参数指定引用计数为0时的行为,即是unlock    {        lock(mutexPtr.get());//mutexPtr.get()返回mutexPtr管理对象的原生类型    }private:    shoread_ptr<Mutex> mutexPtr;};

在资源管理类中提供对原始资源的访问也是一个重要的功能。

对于share_ptr,它提供了get()成员函数,用来执行显式转换,返回智能指针内部的原始指针

对与我们自定义资源管理类,有两种方式提供对原始资源的访问:显式转换函数和隐式转换函数

//假设我们有这样一个类class Font{public:    explicit Font(FontHandle fg):f(fh){}private:    FontHandle f;};

其显式转换函数形式为

FontHanld get() const { return f; }

其隐式转换函数形式为

operateor FontHandle() const { return f; }

这两种形式各有好处,隐式转换的好处是比较自然,但是会增加错误发生机会,例如我们本想得到一个Font,结果却意外得到FontHandle

Font f1(getFont());FontHandle f2=f1;//这里会将Font转型为FontHandle,假如这不是你想要的呢?这个错误很隐蔽

在使用智能指针时会发生一个问题,如果有一个函数是以下形式:

process( shared_ptr<Investment> (new Investment),priority );

这条语句有三个动作:

调用unlock,执行new Investment,调用shared_ptr构造函数。我们知道,new Investment动作一定在shared_ptr构造函数之前,另外C++对构造函数内动作的次序是无定义的,如果unlock动作发生在第二顺位,并且如果它的调用导致异常,此时new Investment返回的指针会遗失,引发资源泄露。对此,解决方法是先建立好智能指针。

shared_ptr<Investment> p(new Investment);process(p,priority);

总结起来便是,以独立语句将newed对象置入智能指针。

上一篇: Day01

下一篇: 关于闭包