当前位置:编程学习 > C/C++ >>

在C++中实现事件(委托)(续)

其实要改成真正的C#版,我们主要要做2件事, 一是吧CEventHandler放到外面,可以让外部直接构造, 二是实现operator +=和operator -=, 下面是我的实现代码:
#pragma once
 
#include <functional>
#include <algorithm>
#include <vector>
#include <assert.h>
 
namespace Common
{
    typedef void* cookie_type;
 
    template<typename TR, typename T1, typename T2>
    class CEventHandler 
    {
    public:
        typedef TR return_type;
        typedef T1 first_type;
        typedef T2 second_type;
 
        typedef std::function<return_type (first_type, second_type)> handler_type;
 
        CEventHandler(const CEventHandler& h)
        {
            _handler = h._handler;
            assert(_handler != nullptr);
        }
 
        CEventHandler(handler_type h)
        {
            _handler = h;
            assert(_handler != nullptr);
        }
 
        template<typename class_type, typename class_fun>
        CEventHandler(class_type* pThis, class_fun object_function)
        {
            using namespace std::placeholders;
            _handler = std::bind(object_function, pThis, _1, _2);
            assert(_handler != nullptr);
        }
 
        return_type operator()(first_type p1, second_type p2)
        {
            return_type ret = return_type();
            assert(_handler != nullptr);
            if(_handler != nullptr) ret = _handler(p1, p2);
            return ret;
        }
 
        handler_type _handler;
    };
 
    template<typename EventHandler>
    class CEvent
    {
    public:
        typedef EventHandler event_handler_type;
        typedef typename event_handler_type::return_type return_type;
        typedef typename event_handler_type::first_type first_type;
        typedef typename event_handler_type::second_type second_type;
        typedef typename event_handler_type::handler_type handler_type;
 
        ~CEvent()
        {
            Clear();
        }
 
        return_type operator()(first_type p1, second_type p2)
        {
            return_type ret = return_type();
            size_t size = _handlers.size();
            for(auto p : _handlers)
            {
                ret = p->operator()(p1, p2);
            }
            return ret;
        }
 
        cookie_type AddHandler(const event_handler_type& h)
        {
            event_handler_type*p = new(nothrow)  event_handler_type(h);
            if(p != nullptr) _handlers.push_back(p);
            return (cookie_type)p;
        }
 
        void RemoveHandler(cookie_type cookie)
        {
            event_handler_type* p = (event_handler_type*)cookie;
 
            auto itr = std::find(_handlers.begin(), _handlers.end(), p);
            if(itr != _handlers.end())
            {
                _handlers.erase(itr);
                delete p;
            }
            else
            {
                assert(false);
            }
        }
 
        cookie_type operator += (const event_handler_type& pHandler)
        {
            return AddHandler(pHandler);
        }
 
        void operator -= (cookie_type cookie)
        {
            RemoveHandler(cookie);
        }
 
        void Clear()
        {
            if(!_handlers.empty())
            {
                int n = _handlers.size();
                std::for_each(_handlers.begin(), _handlers.end(), [](event_handler_type* p)
                { 
                    assert(p != nullptr);
                    delete p;
                });
                _handlers.clear();        
            }
        }
 
    private:
        std::vector<event_handler_type*> _handlers;
    };
 
} //Common
 
然后我们就可以这样使用了:
// EventTest.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
 
#include <iostream>
#include &
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,