EffectiveC++学习笔记-条款14

来源:互联网 发布:java copy文件 编辑:程序博客网 时间:2024/05/16 08:41

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

例如我们现在要处理一个Mutex互斥的对象,有lock和unlock使用。

void lock(Mutex* pm);void unlock(Mutex* pm);

然后建立一个class用来管理锁。

class Lock{public:    explicit Lock(Mutex* pm):mutexPtr(pm)    {        lock(mutexPtr);//获取资源    }    ~Lock()    {        unlock(mutexPtr)//释放资源    }private:    Mutex mutexPtr;

我们这样就可以放心使用Lock了。

现在的问题是当我们Lock对象被复制会发生什么。

Lock m1(&m);Lock m2 = m1;

我们有两种或者更多其他选择:

  1. 禁止复制
    class Lock : private Uncopyable{};

  2. 使用引用计数法
    我们可以使用tr1::shared_ptr< Mutex >但是引用次数为0它将删除Mutex,而我们需要的是解除锁定。

幸运的是shared_ptr可以指定“删除器”也就是引用次数为0时被调用。

class Lock{    //指定删除器为 unlock    explicit Lock(Mutex* pm):mutexPtr(pm,unlock)    {        lock(mutexPtr);    }private:    std::tr1::shared_ptr<Mutex> mutexPtr;}

这样就不需要声明析构函数了。

实现一个仿函数

其实那个删除器的名字又称为仿函数。
仿函数是什么?
不是函数但可以像函数一样使用,因为重载了operator()
例如

//定制仿函数template<class T>struct Less{    //T类型必须实现了operator<运算符    bool operator()(const T& l, const T& r)    {        return l < r;    }};

下面我们实现一个带有删除器的智能指针

template<class T>//注意这里有模版  默认new申请内存释放struct Del{    void operator()(const T* ptr)    {        delete ptr;    }};struct Free//注意这里没有模版  对应malloc申请内存{    void operator()(void* ptr)    {        free(ptr);    }};//带有默认删除器 Deltemplate<class T, class Deleter = Del<T>>class SharedPtr{public:    SharedPtr(T* ptr, Deleter del) :        m_ptr(ptr),        m_count(new long(1)),        m_del(del)  {}    SharedPtr(T* ptr):        m_ptr(ptr),        m_count(new long(1)) {}    ~SharedPtr()    {        release();    }protected:    void release()    {        if(--*m_count == 0)        {            m_del(m_ptr);            delete m_count;            m_count = nullptr;                    cout <<"del"<<endl;        }    }private:    T*      m_ptr;    long*   m_count;    Deleter m_del;};void test(){    SharedPtr<int>sp1(new int(1));    SharedPtr<int,Free>sp2((int*)malloc(sizeof(int) * 10), Free());//注意怎么调用的}

完成!