ScopeGuard

目前看到的


ScopeGuard的有個比較能用的上的地方就是,如果需要退出時執行某個操作,可以和方便的使用,而不需要用try finally。不管裏面是否拋出異常,都會執行到我們必須執行的函數

實現也是利用了構造和析構函數,在構造函數中,將需要調用的函數地址傳入,在析構時調用

class ScopeGuardImplBase
    {
        /// Copy-assignment operator is not implemented and private.
        ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);

    protected:

        ~ScopeGuardImplBase()
        {}

        /// Copy-constructor takes over responsibility from other ScopeGuard.
        ScopeGuardImplBase(const ScopeGuardImplBase& other) throw()
            : dismissed_(other.dismissed_)
        {
            other.Dismiss();
        }

        template <typename J>
        static void SafeExecute(J& j) throw()
        {
            if (!j.dismissed_)
                try
                {
                    j.Execute();
                }
                catch(...)
                {}
        }
       
        mutable bool dismissed_;

    public:
        ScopeGuardImplBase() throw() : dismissed_(false)
        {}

        void Dismiss() const throw()
        {
            dismissed_ = true;
        }
    };


沒有參數的函數指針的實現

template <typename F>
    class ScopeGuardImpl0 : public ScopeGuardImplBase
    {
    public:
        static ScopeGuardImpl0<F> MakeGuard(F fun)
        {
            return ScopeGuardImpl0<F>(fun);
        }

        ~ScopeGuardImpl0() throw()
        {
            SafeExecute(*this);
        }

        void Execute()
        {
            fun_();
        }

    protected:
        ScopeGuardImpl0(F fun) : fun_(fun)
        {}

        F fun_;
    };

也可以出一個全局的工廠構造

template <typename F>
    inline ScopeGuardImpl0<F> MakeGuard(F fun)
    {
        return ScopeGuardImpl0<F>::MakeGuard(fun);
    }

多個參數,成員函數都可以類似擴展實現

使用,函數退出時候肯定會執行HasNone()函數了

void DoStandaloneFunctionTests()
{
    ::Loki::ScopeGuard guard0 = ::Loki::MakeGuard( &HasNone );

}

另外不想執行的話可以通過guard0.Dismiss();放棄


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章