`
暴风雪
  • 浏览: 377612 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

《Effective C艹》读书笔记(10)

    博客分类:
  • C艹
 
阅读更多

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

     修改了一下书中代码(参考http://www.cnblogs.com/jerry19880126/archive/2013/05/25/3098997.html)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<memory>
using namespace std;
class Lock {
    public:
    Lock(int *pm)
    : mutexPtr(pm){
         lock(mutexPtr);
    }
    ~Lock(){
         unlock(mutexPtr);
    }
    private:
    int *mutexPtr;
    void lock(int* a){
        cout<<"adress is "<<a<<"is locked\n";
    }
    void unlock(int* a){
        cout<<"adress is "<<a<<"is unlock\n";
    }
};

int main(){
    Lock a(new int(10));
    Lock b(a);
    return 0;
}

 运行程序可以发现输出为

adress is 0x590cc8is locked

adress is 0x590cc8is unlock

adress is 0x590cc8is unlock

 

    也就是说,locked执行了一次,但是unlock却执行了两次。两个对象中的指针指向同一个资源,如果unlock中对内存进行读取修改的话,是非常有可能出错的、

    解决上述问题有两种方法,一种是条款6,直接禁止赋值函数以及拷贝构造函数

class Lock {
    public:
    Lock(int *pm)
    : mutexPtr(pm){
         lock(mutexPtr);
    }
    ~Lock(){
         unlock(mutexPtr);
    }
    private:
    int *mutexPtr;
    void lock(int* a){
        cout<<"adress is "<<a<<"is locked\n";
    }
    void unlock(int* a){
        cout<<"adress is "<<a<<"is unlock\n";
    }

    Lock& operator=(const Lock&);
    Lock(const Lock&);
};

     这样便无法使用赋值函数和拷贝构造函数(一旦使用会提示你编译不通过)

 

    第二种是对底层资源使用”引用计数法“。有时候我们又希望保有资源,直到它的最后一个使用者被销毁。这种情况下复制RAII对象时,应该将资源的”被引用计数“递增。tr1::shared_ptr便是如此。

class Lock {
    public:
    Lock(int *pm)
    :mutexPtr(pm){
         lock(mutexPtr);
    }
    ~Lock(){
         unlock(mutexPtr);
    }
    private:
    shared_ptr<int> mutexPtr;
    void lock(shared_ptr<int> mutexPtr){
        cout<<"adress is "<<"is locked\n";
    }
    void unlock(shared_ptr<int> mutexPtr){
        cout<<"adress is "<<"is unlock\n";
    }
};

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics