您的位置:首页 > 编程语言 > C语言/C++

《Effective C++》学习笔记条款14 在资源管理类中小心拷贝行为

2013-12-18 21:45 260 查看
                                                 
条款14:在资源管理类中小心拷贝行为
    我们在条款13中讨论的资源表现在堆上申请的资源,而有些资源并不适合被auto_ptr和tr1::shared_ptr所管理。可能
我们需要建立自己的资源管理类。

    例:

     void lock(Mutex *pm);     //锁定pm所指的互斥量

     unlock(Mutex *pm);        //将pm解除锁定

     
我们建立的资源管理类可能会是这样:

     class Lock 

    {

        public: 

        explicit Lock(Mutex *pm)

        : mutexPtr(pm) 

        {

             lock(mutexPtr); 

        } 

        ~Lock() 

        { 

             unlock(mutexPtr); 

        } 

        private: 

        Mutex *mutexPtr; 

    }; 
  
 
但是,如果Lock对象被复制,会发生什么事???

    
“当一个RAII对象被复制,会发生什么事?”大多数时候你会选择一下两种可能:
禁止复制。如果复制动作对RAII类并不合理,你便应该禁止之。禁止类的copying函数参见条款6。

对底层资源使用”引用计数法“。有时候我们又希望保有资源,直到它的最后一个使用者被销毁。这种情况下复制RAII对象时,应该将资源的”被引用计数“递增。tr1::shared_ptr便是如此。
    
通常只要内含一个tr1::shared_ptr成员变量,RAII类便可实现”引用计数“行为。

     class Lock 

    {

        public: 

            explicit Lock(Mutex*pm) 
           : mutexPtr(pm, unlock)        //由于tr1::shared_ptr缺省行为是”当引用计数为0时删除其所指物“,幸运的是     
                                                //我们可以指定”引用计数“为9时被调用的所谓”删除器“,即第二个参数unlock

        { 

            lock(mutexPtr.get()); 

        } 

        private:

            std::tr1::shared_ptr<Mutex> mutexPtr; 

     }; 
    
本例中,并没说明析构函数,因为没有必要。编译器为我们生成的析构函数会自动调用其non-static成员变量
(mutexPtr)的析构函数。而mutexPtr的析构函数会在互斥量”引用计数“为0时自动调用tr1::shared_ptr的删除器
(unlock)。

   
 Copying函有可能被编译器自动创建出来,因此除非编译器所生成版本做了你想要做的事,否则你得自己编写它们。

   
 请记住:
复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定RAII对象的copying行为。

普遍而常见的RAII类拷贝行为是:抑制拷贝,施行引用计数法。不过其它行为也可能被实现。   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息