乱七八糟,有空再整理。


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 
                } 
            } 
            else 
            
                (*(F)_handlers[i].second)(a, b); 
            } 
        } 
    } 
}; 


int main(int argc, char* argv[]) 

    Test t; 
    DWORD cur = GetTickCount (); 
    for (int i=0; i<10000000; i++) 
    
        t.test0(); 
    } 
    cout << (GetTickCount() - cur) << endl; 

    Functor <void> f; 
    f.add (make_pair(&t, &Test::test0)); 
    f.add (test0); 
    cur = GetTickCount (); 
    for (int i=0; i<1000000; i++) 
    
        f.call(); 
    } 
    cout << (GetTickCount() - cur) << endl; 

    f.call ();

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

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

转载于:https://www.cnblogs.com/cpunion/archive/2005/07/22/198288.html

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

  1. Java趣谈——如何构建一个高效且可伸缩的缓存

    Java趣谈--如何构建一个高效且可伸缩的缓存 本集概要: 怎样构建一个线程安全而又高效.可伸缩的缓存? 怎样利用设计模式,把缓存做成通用的工具? 除了synchronize和volatile,我们还 ...

  2. 百度提出PADDLESEG:一个高效的图像分割开发工具

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 小白导读 论文是学术研究的精华和未来发展的明灯.小白决心每天为大家 ...

  3. 一个高效的定时任务系统

    "今天想跟大家一起探讨一个听起来很简单的话题:定时任务机制. 无非就是一个计时器,到了指定时间就开始跑呗.too young,要是这么简单我还说啥呢,干不就完了. 那如果是几千上万个定时任务 ...

  4. 自己构建一个高效缓存服务!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:分享一个牛逼的 Java 开源后台管理系统,不要造轮子了!个人原创+1博客:点击前往,查看更多 作者:flyde ...

  5. 如何写一个高效进程/线程池_关于高效企业测试的思考(1/6)

    如何写一个高效进程/线程池 企业中的测试仍然没有得到应有的广泛应用. 编写尤其是维护测试需要花费时间和精力,但是缩短软件测试并不是解决方案. 为了提高测试效率,应该追求哪些范围,方法和测试技术? 基于 ...

  6. python画画bup_Python中的高效Vector / Point类

    实现高效的Vector / Point类的最佳方法是什么(甚至更好:是否有一个),可以在 Python 2.7和3.x中使用? 我找到了the blender-mathutils,但它们似乎只支持Py ...

  7. failed to open log file_C++中glog源码剖析以及如何设计一个高效 log模块

    每个开发者编程中都会记录log信息,多数人都会使用log第三方库,log库使用起来很方便,但我们也需要了解log系统的原理,这里以glog为例进行分析. 开始 这里不会介绍glog中是如何控制INFO ...

  8. 线程安全list_多线程开发之如何创建一个线程安全的类

    上一篇讨论了如何解决线程安全的问题,今天总结如何设计一个线程安全的类: 创建线程安全类的关注点 一个类要想线程安全,除了上一篇文章通过外部解决方式外,还可以通过合理的设计类的内部来解决,使类本身就线程 ...

  9. 优雅地实现一个高效、异步数据实时刷新的列表

    今日科技快讯 2月11日消息,据CNBC报道,当特斯拉公司于2019年1月宣布第二轮裁员以控制成本时,一个关键部门受到的打击尤为沉重.两名被裁汰的员工表示,负责向北美地区客户交付Model 3电动汽车 ...

最新文章

  1. bootstrap的日期选择器 完整源码demo附效果图
  2. 文本挖掘预处理之向量化与Hash Trick
  3. 【Java核心计算 基础知识(第9版)】第3章 Java的基本程序设计结构
  4. 简单API接口签名验证
  5. Opengl超级宝典笔记——空间绘图画点
  6. [蓝桥杯][算法提高VIP]最小乘积(提高型)-排序
  7. zzulioj1111: 多个整数的逆序输出(函数专题)
  8. 【软件架构】三层架构和MVC的比较
  9. PCI、PCI-X、PCI-E AGP区别
  10. 启明星系统简介--兼论启明星OA思想
  11. 广州市车联网先导区建设总体技术规范
  12. 8 - 博客文章详情页
  13. 【Web安全笔记】之【9.0 工具与资源】
  14. 关于java一些星号三角形的实现
  15. IBDP tok课程是什么课?怎么拿高分?
  16. 著名数学家龚升的论述揭示高中“函数近代严格定义” 有非常明显错误
  17. 《程序员升职记》2.繁忙的收发室
  18. Uboot9之uboot目录分析
  19. java字母数字互相转换
  20. TCP多人聊天室实现 JSON文件解析

热门文章

  1. vue 如何处理两个组件异步问题_Vue异步组件处理路由组件加载状态的解决方案...
  2. 用一句话阐明epoll跟Windows IOCP之间的区别
  3. 安卓7.0海信定制版新增功能
  4. [整理] TPM 2.0 设备串口通讯协议中文文档
  5. 地图整饰-框架与格网
  6. 走在网页游戏开发的路上——页游资源管理
  7. matlab线性代数命令大全,线性代数 - MATLAB 系统中文帮助手册
  8. python 柱状图上显示字体_Python爬取百部电影数据,我发现了这个惊人真相!
  9. hive 中String对长度没有限制
  10. 熊海博客php版本,xhcms_v1.0 熊海CMS是由熊海开发的一款可广泛应用于个人博客 联合开发网 - pudn.com...