Finally in C++

后端 未结 6 1533
南旧
南旧 2020-12-28 08:33

Is this a good way to implement a Finally-like behavior in standard C++? (Without special pointers)

class Exception : public Exception
    { public: virtual          


        
6条回答
  •  死守一世寂寞
    2020-12-28 09:15

    Assuming you are looking to delete the pointer myObject and avoid memory leaks, your code can still fail to do this if there is a "return" statement in the code where you say // Do something with myObject. (I am assuming real code would be here)

    RAII techniques have the relevant action that is equivalent to a "finally" block, in a particular object's destructor:

    class ResourceNeedingCleanup
    {
      private:
        void cleanup(); // action to run at end
      public:
        ResourceNeedingCleanup( /*args here*/) {}
        ~ResourceNeedingCleanup() { cleanup(); }  
    
        void MethodThatMightThrowException();
    };
    
    typedef boost::shared_ptr ResourceNeedingCleanupPtr;
    // ref-counted smart pointer
    
    
    class SomeObjectThatMightKeepReferencesToResources
    {
       ResourceNeedingCleanupPtr pR;
    
       void maybeSaveACopy(ResourceNeedingCleanupPtr& p)
       {
          if ( /* some condition is met */ )
             pR = p;
       }
    };
    
    // somewhere else in the code:
    void MyFunction(SomeObjectThatMightKeepReferencesToResources& O)
    {
       ResourceNeedingCleanup R1( /*parameters*/) ;
       shared_ptr pR2 = 
            new ResourceNeedingCleanup( /*parameters*/ );
       try
       {
          R1.MethodThatMightThrowException();
          pR2->MethodThatMightThrowException();
          O->maybeSaveACopy(pR2);
       }
       catch ( /* something */ )
       {
          /* something */
       }
    
       // when we exit this block, R1 goes out of scope and executes its destructor
       // which calls cleanup() whether or not an exception is thrown.
       // pR2 goes out of scope. This is a shared reference-counted pointer. 
       // If O does not save a copy of pR2, then pR2 will be deleted automatically
       // at this point. Otherwise, pR2 will be deleted automatically whenever
       // O's destructor is called or O releases its ownership of pR2 and the
       // reference count goes to zero.
    }
    

    I think I have the semantics correct; I haven't used shared_ptr much myself, but I prefer it to auto_ptr<> -- a pointer to an object can only be "owned" by one auto_ptr<>. I've used COM's CComPtr and a variant of it that I've written myself for "regular" (non-COM) objects that is similar to shared_ptr<> but has Attach() and Detach() for transfer of pointers from one smart pointer to another.

提交回复
热议问题