Is there a favored idiom for mimicing Java's try/finally in C++?

前端 未结 15 780
无人及你
无人及你 2021-02-05 19:16

Been doing Java for number of years so haven\'t been tracking C++. Has finally clause been added to C++ exception handling in the language definition?<

15条回答
  •  粉色の甜心
    2021-02-05 19:53

    Thought I'd add my own solution to this - a kind of smart pointer wrapper for when you have to deal with non-RAII types.

    Used like this:

    Finaliser< IMAPITable, Releaser > contentsTable;
    // now contentsTable can be used as if it were of type IMAPITable*,
    // but will be automatically released when it goes out of scope.
    

    So here's the implementation of Finaliser:

    /*  Finaliser
        Wrap an object and run some action on it when it runs out of scope.
        (A kind of 'finally.')
        * T: type of wrapped object.
        * R: type of a 'releaser' (class providing static void release( T* object )). */
    template< class T, class R >
    class Finaliser
    {
    private:
        T* object_;
    
    public:
        explicit Finaliser( T* object = NULL )
        {
            object_ = object;
        }
    
        ~Finaliser() throw()
        {
            release();
        }
    
        Finaliser< T, R >& operator=( T* object )
        {
            if (object_ != object && object_ != NULL)
            {
                release();
            }
            object_ = object;
    
            return *this;
        }
    
        T* operator->() const
        {
            return object_;
        }
    
        T** operator&()
        {
            return &object_;
        }
    
        operator T*()
        {
            return object_;
        }
    
    private:
        void release() throw()
        {
            R::release< T >( object_ );
        }
    };
    

    ... and here's Releaser:

    /*  Releaser
        Calls Release() on the object (for use with Finaliser). */
    class Releaser
    {
    public:
        template< class T > static void release( T* object )
        {
            if (object != NULL)
            {
                object->Release();
            }
        }
    };
    

    I have a few different kinds of releaser like this, including one for free() and one for CloseHandle().

提交回复
热议问题