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

乱七八糟,有空再整理。

1、暂命名为Functor,因为没考虑返回值的情况,这在多分派委托处理中,算是个麻烦事,以后类名可能改为Delegate。
2、根据i_like_cpp翻译的技术文章《 成员函数指针与高性能的C++委托》提供的思路做成的,不过原文所提到的FastDelegate实现太复杂,所以自己做了一个,可能不完善,不过初步测试基本功能达到了,而且实现要简单一些。
3、原本vector遍历用的是迭代器,不过测试发现速度比用下标访问慢10倍以上,改成下标访问,测试表明速度已经和直接调用差不多。实际测试结果非常相近,用GetTickCount获取的结果,有时是直接调用要快一些,有时是使用Functor要快一些,当然Functor不可能比直接调用还快。
4、实现没有写完,先写了3个版本做测试用,成型以后会实现更多版本(支持更多参数)。下午一时心血来潮写成的,离成型还很远,不过从效率测试来看值得做。


None.gif #include  < vector >  
None.gif#include 
< functional >  
None.gif#include 
< iostream >  
None.gif#include 
< string >  
None.gif#include 
< windows.h >  
None.gif
using   namespace  std; 
None.gif
None.gif
struct  Test 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
int n; 
ExpandedSubBlockStart.gifContractedSubBlock.gif    Test () : n(
3dot.gif{} 
InBlock.gif    
void test0() 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
//cout << "Test::test0: " << n << endl; 
ExpandedSubBlockEnd.gif
    }
 
InBlock.gif
InBlock.gif    
void test1(int i) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
//cout << "Test::test1: " << i << endl; 
ExpandedSubBlockEnd.gif
    }
 
InBlock.gif
InBlock.gif    
void test2(const string& a, int b) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
//cout << "Test::test2: " << a << "|" << b << endl; 
ExpandedSubBlockEnd.gif
    }
 
ExpandedBlockEnd.gif}

None.gif
None.gif
void  test0 () 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
//cout << "test0" << endl; 
ExpandedBlockEnd.gif
}
 
None.gif
None.gif
void  test1 ( int  i) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
//cout << "test1: " << i << endl; 
ExpandedBlockEnd.gif
}
 
None.gif
None.gif
void  test2( const   string &  a,  int  b) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
//cout << "test2: " << a << "|" << b << endl; 
ExpandedBlockEnd.gif
}
 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
struct  NullType  dot.gif {}
None.gif
None.giftemplate 
< typename R, typename A = NullType, typename B = NullType, typename C = NullType, 
None.giftypename D
= NullType, typename E = NullType, typename F = NullType, typename G = NullType, 
None.giftypename H
= NullType, typename I = NullType, typename J = NullType, typename K = NullType, 
None.giftypename L
= NullType, typename M = NullType, typename N = NullType, typename O = NullType >  
None.gif
class  Functor 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
ExpandedBlockEnd.gif}

None.gif
None.giftemplate 
< typename R >  
None.gif
struct  Functor  < R >  
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    vector 
<pair<void*void*> > _handlers; 
InBlock.gif    typedef R(
*F)(); 
InBlock.gif
InBlock.gif    
void add (F f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    template 
<typename T> 
InBlock.gif    
void add (const pair<T*, typename R(T::*)()>& f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        typedef R(T::
*P)(); 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
struct Pointer dot.gif{P p;}
ExpandedSubBlockStart.gifContractedSubBlock.gif        Pointer ptr 
= dot.gif{f.second}
InBlock.gif        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    
void call () 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
for (size_t i=0; i<_handlers.size (); i++
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
void* p = _handlers[i].first; 
InBlock.gif            
if (p) // member function 
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif
InBlock.gif                
void* mem_fun = _handlers[i].second; 
ExpandedSubBlockStart.gifContractedSubBlock.gif                __asm
dot.gif
InBlock.gif                    mov ecx, p 
InBlock.gif                    call mem_fun 
ExpandedSubBlockEnd.gif                }
 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                (
*(F)_handlers[i].second)(); 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}

None.gif
None.giftemplate 
< typename R, typename A >  
None.gif
struct  Functor  < R, A >  
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    vector 
<pair<void*void*> > _handlers; 
InBlock.gif    typedef R(
*F)(A); 
InBlock.gif
InBlock.gif    
void add (F f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    template 
<typename T> 
InBlock.gif    
void add (const pair<T*, typename R(T::*)(A)>& f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        typedef R(T::
*P)(A); 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
struct Pointer dot.gif{P p;}
ExpandedSubBlockStart.gifContractedSubBlock.gif        Pointer ptr 
= dot.gif{f.second}
InBlock.gif        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    
void call (A a) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
for (size_t i=0; i<_handlers.size (); i++
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
void* p = _handlers[i].first; 
InBlock.gif            
if (p) // member function 
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif
InBlock.gif                
void* mem_fun = _handlers[i].second; 
ExpandedSubBlockStart.gifContractedSubBlock.gif                __asm
dot.gif
InBlock.gif                    push a 
InBlock.gif                    mov ecx, p 
InBlock.gif                    call mem_fun 
ExpandedSubBlockEnd.gif                }
 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                (
*(F)_handlers[i].second)(a); 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}

None.gif
None.giftemplate 
< typename R, typename A, typename B >  
None.gif
struct  Functor  < R, A, B >  
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    vector 
<pair<void*void*> > _handlers; 
InBlock.gif    typedef R(
*F)(A, B); 
InBlock.gif
InBlock.gif    
void add (F f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        _handlers.push_back (make_pair ((
void*)0, (void*)f)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    template 
<typename T> 
InBlock.gif    
void add (const pair<T*, typename R(T::*)(A, B)>& f) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        typedef R(T::
*P)(A, B); 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
struct Pointer dot.gif{P p;}
ExpandedSubBlockStart.gifContractedSubBlock.gif        Pointer ptr 
= dot.gif{f.second}
InBlock.gif        _handlers.push_back (make_pair ((
void*)f.first, *(void**)&ptr)); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif
InBlock.gif    
void call (A a, B b) 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
for (size_t i=0; i<_handlers.size (); i++
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
void* p = _handlers[i].first; 
InBlock.gif            
if (p) // member function 
ExpandedSubBlockStart.gifContractedSubBlock.gif
            dot.gif
InBlock.gif                
void* mem_fun = _handlers[i].second; 
ExpandedSubBlockStart.gifContractedSubBlock.gif                __asm
dot.gif
InBlock.gif                    push b 
InBlock.gif                    push a 
InBlock.gif                    mov ecx, p 
InBlock.gif                    call mem_fun 
ExpandedSubBlockEnd.gif                }
 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                (
*(F)_handlers[i].second)(a, b); 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}

None.gif
None.gif
None.gif
int  main( int  argc,  char *  argv[]) 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    Test t; 
InBlock.gif    DWORD cur 
= GetTickCount (); 
InBlock.gif    
for (int i=0; i<10000000; i++
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        t.test0(); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif    cout 
<< (GetTickCount() - cur) << endl; 
InBlock.gif
InBlock.gif    Functor 
<void> f; 
InBlock.gif    f.add (make_pair(
&t, &Test::test0)); 
InBlock.gif    f.add (test0); 
InBlock.gif    cur 
= GetTickCount (); 
InBlock.gif    
for (int i=0; i<1000000; i++
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        f.call(); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif    cout 
<< (GetTickCount() - cur) << endl; 
InBlock.gif
InBlock.gif    f.call ();
InBlock.gif
InBlock.gif    Functor
<voidint> f1; 
InBlock.gif    f1.add (test1); 
InBlock.gif    f1.add (make_pair (
&t, &Test::test1)); 
InBlock.gif    f1.add (test1); 
InBlock.gif    f1.add (test1); 
InBlock.gif    f1.call (
93); 
InBlock.gif
InBlock.gif    Functor
<voidconst string&int> f2; 
InBlock.gif    f2.add (test2); 
InBlock.gif    f2.add (make_pair (
&t, &Test::test2)); 
InBlock.gif    f2.add (test2); 
InBlock.gif    f2.add (test2); 
InBlock.gif    f2.call (
string("hello"), 5); 
InBlock.gif    
return 0
ExpandedBlockEnd.gif}
 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值