当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

实现一个高效C++委托类(多分派)

    1、暂命名为Functor,因为没考虑返回值的情况,这在多分派委托处理中,算是个麻烦事,以后类名可能改为Delegate.

    2、根据i_like_cpp翻译的技术文章《成员函数指针与高性能的C++委托》提供的思路做成的,不过原文所提到的FastDelegate实现太复杂,所以自己做了一个,可能不完善,不过初步测试基本功能达到了,而且实现要简单一些。

    3、原本vector遍历用的是迭代器,不过测试发现速度比用下标访问慢10倍以上,改成下标访问,测试表明速度已经和直接调用差不多。实际测试结果非常相近,用GetTickCount获取的结果,有时是直接调用要快一些,有时是使用Functor要快一些,当然Functor不可能比直接调用还快。

    4、实现没有写完,先写了3个版本做测试用,成型以后会实现更多版本(支持更多参数)。下午一时心血来潮写成的,离成型还很远,不过从效率测试来看值得做。

 #include <vector>
#include <functional>
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;

struct Test
{
    int n;
    Test () : n(3) {}
    void test0()
    {
        cout << "Test::test0: " << n << endl;
    }

    void test1(int i)
    {
        cout << "Test::test1: " << i << endl;
    }

    void test2(const string& a, int b)
    {
        cout << "Test::test2: " << a << "|" << b << endl;
    }
};

void test0 ()
{
    cout << "test0" << endl;
}

void test1 (int i)
{
    cout << "test1: " << i << endl;
}

void test2(const string& a, int b)
{
    cout << "test2: " << a << "|" << b << endl;
}

struct NullType {};

template <typename R, typename A=NullType, typename B=NullType, typename C=NullType,
typename D=NullType, typename E=NullType, typename F=NullType, typename G=NullType,
typename H=NullType, typename I=NullType, typename J=NullType, typename K=NullType,
typename L=NullType, typename M=NullType, typename N=NullType, typename O=NullType>
class Functor { };

template <typename R>
struct Functor <R>
{
    vector <pair<void*, void*> > _handlers;
    typedef R(*F)();

    void add (F f)
    {
        _handlers.push_back (make_pair ((void*)0, (void*)f));
    }

    template <typename T>
    void add (const pair<T*, typename R(T::*)()>& f)
    {
        typedef R(T::*P)();
        struct Pointer {P p;};
        Pointer ptr = {f.second};
        _handlers.push_back (make_pair ((void*)f.first, *(void**)&ptr));
    }

    void call ()
    {
        for (size_t i=0; i<_handlers.size (); i++)
        {
            void* p = _handlers[i].first;
            if (p) // member function
            {
                void* mem_fun = _handlers[i].second;
                __asm{
                    mov ecx, p
                    call mem_fun
                }
            }
            else
            {
                (*(F)_handlers[i].second)();
            }
        }
    }
};

template <typename R, typename A>
struct Functor <R, A>
{
    vector <pair<void*, void*> > _handlers;
    typedef R(*F)(A);

    void add (F f)
    {
        _handlers.push_back (make_pair ((void*)0, (void*)f));
    }

    template <typename T>
    void add (const pair<T*, typename R(T::*)(A)>& f)
    {
        typedef R(T::*P)(A);
        struct Pointer {P p;};
        Pointer ptr = {f.second};
        _handlers.push_back (make_pair ((void*)f.first, *(void**)&ptr));
    }

    void call (A a)
    {
        for (size_t i=0; i<_handlers.size (); i++)
        {
            void* p = _handlers[i].first;
            if (p) // member function
            {
                void* mem_fun = _handlers[i].second;
                __asm{
                    push a
                    mov ecx, p
                    call mem_fun
                }
            }
            else
            {
                (*(F)_handlers[i].second)(a);
            }
        }
    }
};

template <typename R, typename A, typename B>
struct Functor < R , A , B >
{
    vector <pair<void*, void*> > _handlers;
    typedef R(*F)(A, B);

    void add (F f)
    {
        _handlers.push_back (make_pair ((void*)0, (void*)f));
    }

template <typename T>
    void add (const pair<T*, typename R(T::*)(A, B)>& f)
    {
   typedef R(T::*P)(A, B);
   struct Pointer {P p;};
        Pointer ptr = {f.second};
        _handlers.push_back (make_pair ((void*)f.first, *(void**)&ptr));
    }

    void call (A a, B b)
    {
        for (size_t i=0; i<_handlers.size (); i++)
        {
            void* p = _handlers[i].first;
            if (p) // member function
            {
                void* mem_fun = _handlers[i].second;
                __asm{
                    push b
                    push a
                    mov ecx, p
                    call mem_fun
                }

     //T *obj = (T *)_handlers[i].first;
     //Pointer &ptr = (Pointer&)_handlers[i].second;
     //P p = ptr.p;
     //(obj->*p)(a,b);
            }
            else
            {
                (*(F)_handlers[i].second)(a, b);
            }
        }
    }
};


int main(int argc, char* argv[])
{
    Test t;

    Functor <void> f;
    f.add (make_pair(&t, &Test::test0));
    f.add (test0);
    f.call ();

    Functor<void, int> f1;
    f1.add (make_pair (&t, &Test::test1));
    f1.add (test1);
    f1.call (93);

    Functor< void, const string&, int > f2;
    f2.add (make_pair (&t, &Test::test2));
    f2.add (test2);
    f2.call (string("hello"), 5);
getchar();
    return 0;
}

相关内容
赞助商链接