zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 14: Think carefully about copying behavior in resource-managing classes.

    For example, suppose you’re using a C API to manipulate mutex objects of type Mutex offering functions lock and unlock:

    void lock(Mutex *pm); // lock mutex pointed to by pm
    void unlock(Mutex *pm); // unlock the mutex

    To make sure that you never forget to unlock a Mutex you’ve locked, you’d like to create a class to manage locks. The basic structure of such a class is dictated by the RAII(Resource Acquisition Is Initialization) principle that resources are acquired during construction and released during destruction:

    class Lock 
    {
    public:
        explicit Lock(Mutex *pm)
            : mutexPtr(pm)
        {
            lock(mutexPtr);
        } // acquire resource
    
        ~Lock() { unlock(mutexPtr); } // release resource
    
    private:
        Mutex *mutexPtr;
    };

    Clients use Lock in the conventional RAII fashion:

    Mutex m; // define the mutex you need to use create block to define critical section
    //...
    {
        Lock ml(&m); // lock the mutex perform critical section operations automatically unlock mutex at end of block 
        // ... 
    } 

    This is fine, but what should happen if a Lock object is copied?

    Lock ml1(&m); // lock m
    Lock ml2(ml1); // copy ml1 to ml2 — what should happen here?

    Most of the time, you’ll want to choose one of the following possibilities:

    1. Prohibit copying

    class Lock : private Uncopyable { // prohibit copying — see Item 6 as before
    public:
        //...  
    };

    2. Reference-count the underlying resource

    Often, RAII classes can implement reference-counting copying behavior by containing a tr1::shared_ptr data member.

    Unfortunately, tr1::shared_ptr’s default behavior is to delete what it points to when the reference count goes to zero, and that’s not what we want.

    Fortunately, tr1::shared_ptr allows specification of a “deleter” — a function or function object to be called when the reference count goes to zero. (This functionality does not exist for auto_ptr, which always deletes its pointer.)

    class Lock {
    public:
        explicit Lock(Mutex *pm) // init shared_ptr with the Mutex to point to and the unlock func as the deleter
            : mutexPtr(pm, unlock) 
        {  
            lock(mutexPtr.get()); // see Item 15 for info on "get"
        }
    private:
        std::tr1::shared_ptr<Mutex> mutexPtr; // use shared_ptr instead of raw pointer
    };

    Things to Remember:

    • Copying an RAII object entails copying the resource it manages, so the copying behavior of the resource determines the copying behavior of the RAII object.
    • Common RAII class copying behaviors are disallowing copying and performing reference counting, but other behaviors are possible.
  • 相关阅读:
    Oracle 11g Release 1 (11.1) 单行函数——比较函数
    HTTP 协议演示——演示(55)
    Oracle 字符串分割函数 splitstr 和 splitstrbyseparators
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——15
    Oracle ——数据库 SQL 分页性能分析
    Oracle ——数据库 Hints
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——35
    Oracle 索引的数据结构
    Bitmap 索引 vs. Btree 索引:如何选择以及何时使用?——25
    回溯法>图的着色问题
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15219843.html
Copyright © 2011-2022 走看看