EffectiveC++学习笔记-条款14

条款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);
    }
};

//带有默认删除器 Del
template<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());//注意怎么调用的
}

完成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值