域守卫C++11泛型实现

//file: scopeguard.h

#ifndef _LOKI_SCOPEGUARD_H
#define _LOKI_SCOPEGUARD_H 1

#include <functional>

namespace loki {

class scope_guard_base {
public:
    void dismiss() noexcept {_bDismissed = true;}

protected:
    scope_guard_base() {}
    scope_guard_base(scope_guard_base&& rhs) : _bDismissed(rhs._bDismissed) {rhs._bDismissed = true;}

    bool _bDismissed = false;
};

template <typename F>
class scope_guard_impl : public scope_guard_base {
public:
    explicit scope_guard_impl(const F& func) : _func(func) {}
    explicit scope_guard_impl(F&& func) : _func(std::move(func)) {}
    scope_guard_impl(scope_guard_impl&& other) : scope_guard_base(std::move(other)) , _func(std::move(other._func)) {}

    ~scope_guard_impl() noexcept {if (!_bDismissed) execute();}

private:
    void* operator new(size_t) = delete;
    void execute() noexcept { _func(); }
    F _func;
};

template <typename F>
scope_guard_impl<typename std::decay<F>::type> makeGuard(F&& func) {return scope_guard_impl<typename std::decay<F>::type>(std::forward<F>(func));}

// 一个由临时变量定义的引用,将导致该临时变量的生命周期延长至和此引用一样长,C++保证临时对象一定会被正确的析构,
// makeGuard产生的临时对象tmpobj,赋给guard, guard生命结束时tmpobj同时析构自己,所以有如下定义
typedef scope_guard_base&& scope_guard;

} //namespace loki

#endif //_LOKI_SCOPEGUARD_H

// test program

struct CMateDatabase {
    void addMate(const std::string& str1stSex, const std::string& str2ndSex) {
        if (str1stSex == str2ndSex) {
            std::cout << "Ha oh!!!!!! :" << std::endl;
            throw 55;
        }
    }
};

class CMate {
public:
    CMate(CMateDatabase* db, const std::string strSex) : _fCount(0), _pDB(db), _strSex(strSex) {}

    std::string getSex() const {return _strSex;}

    void addMate(CMate& newMate) {
        loki::scope_guard sg = loki::makeGuard(std::bind(&CMate::rollback, this, __FUNCTION__, __LINE__));
        _vcMate.push_back(&newMate);
        ++_fCount;
        _pDB->addMate(getSex(), newMate.getSex());
        std::cout << "Here's wishing you both a lifetime of happiness!" << std::endl;
        sg.dismiss();
    }

    size_t countMates() const {return _vcMate.size();}

    unsigned int _fCount;

private:
    void rollback(const char* function, unsigned int line) {
        std::cout << "Ban on same-sex marriage! " << std::endl;
        _vcMate.pop_back();
        --_fCount;
        assert (_vcMate.size() == _fCount);
    }

    std::vector<CMate*> _vcMate;
    CMateDatabase*  _pDB;
    std::string   _strSex;
};


int main(int argc, char *argv[]) {
    CMateDatabase db;
    CMate mate1(&db, "male");
    CMate mate2(&db, "female");
    CMate mate3(&db, "male");
    try {
        mate1.addMate(mate2);
    }
    catch(...) {}

    try {
        mate1.addMate(mate3);
    }
    catch(...) {}

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值