tr1:: 中 function bind 生命周期请教
一个简单的例子,请教一下 怎么管理 SayHello 和 person 对象的生命周期。
- C/C++ code
#include <iostream>using namespace std;#include <memory>#include <functional>using namespace tr1;class Person{public: Person(void) { m_pValue = new int; *m_pValue = 1; } ~Person(void) { cout <<"~Person"<<endl; delete m_pValue; m_pValue = NULL; };public: void SayHello() { cout << "hello , i am a person. this:" <<this<<" value :"<<*m_pValue<<endl; }private: int* m_pValue;};int _tmain(int argc, _TCHAR* argv[]){ tr1::function<void(void)> SayHello; { Person person; SayHello = tr1::bind(&Person::SayHello,&person); SayHello(); } SayHello();//person 已经析构了,这里会有异常 // 是应该我来管理 person 和 SayHello的生命周期?还是我可以在这里判断当前的SayHello对象是否合法? getchar(); return 0;}
[解决办法]
分配一个id做key,不要用function
[解决办法]
我给你一个可以比较的 function 看看吧, 不过这个版本只支持一个参数的, 其它数量的参数按照这个改吧, 也可以做成宏来添加更多参数个数的支持.
它对全局函数和类成员函数直接比较指针, 对函数对象是调用函数对象自身的 operator< 来比较. 如果函数对象也只比较对象指针的话会更简单一些.
- C/C++ code
#include <iostream>#include <string>template <typename Obj_T, typename Src_T>Obj_T union_cast(Src_T src){ // 编译期检查Src_T和Obj_T的数据大小是一致。 // //BOOST_MPL_ASSERT_MSG(sizeof Obj_T == sizeof Src_T, obj_type_size_is_not_same_with_src_type, (Obj_T, Src_T)); union { Src_T m_src; Obj_T m_obj; } tmp_union; tmp_union.m_src = src; return tmp_union.m_obj;}template <typename T>class function;template <typename R, typename A1>class function<R (A1)>{ static const int MAX_MEM_PTR_SIZE = 16; typedef R (function::*caller_type)(A1); typedef int (function::*compair_func)(const function& rhs) const;public: explicit function(R (*global_func)(A1)) : // 全局函数 m_gptr(global_func), m_compair(&function::normal_compair), m_fclass(0), m_func(&function::globle_call) { memset(m_mptr, 0, sizeof(m_mptr)); }; template <class T> explicit function(T* functor) // 函数对象指针 : m_gptr(functor), m_fclass(typeid(T).name()), m_compair(&function::functor_compair<T>), m_func(&function::functor_call<T>) { memset(m_mptr, 0, sizeof(m_mptr)); } template <class T> function(T* pThis, R (T::*member_func)(A1)) : // 成员函数 m_gptr(pThis), m_fclass(0), m_compair(&function::normal_compair), m_func(&function::member_call<T>) { //BOOST_MPL_ASSERT_MSG(sizeof(member_func) < sizeof(m_mptr), member_ptr_is_too_big, (void (T::*)(MsgType&))); //BOOST_MPL_ASSERT_MSG(sizeof(member_func) % 4 == 0, member_ptr_is_not_base_on_4, (void (T::*)(MsgType&))); memcpy_s(m_mptr, sizeof(m_mptr), union_cast<void *>(&member_func), sizeof(member_func)); memset(&m_mptr[sizeof(member_func) / 4], 0, sizeof(m_mptr) - sizeof(member_func)); };public: R call(A1 arg) { return (this->*m_func)(arg); } R operator()(A1 arg) { return call(arg); }private: caller_type m_func; compair_func m_compair; void* m_gptr; const char* m_fclass; unsigned int m_mptr[MAX_MEM_PTR_SIZE];private: R globle_call(A1 arg) { return ((R (*)(A1))(m_gptr))(arg); } template <class T> R member_call(A1 msg) { return ((T*)m_gptr->**union_cast<R (T::**)(A1)>(m_mptr))(msg); } template <class T> R functor_call(A1 msg) { return (*(T*)m_gptr)(msg); }private: int normal_compair(const function& rhs) const { if(this->m_gptr < rhs.m_gptr) return -1; if(this->m_gptr > rhs.m_gptr) return 1; for(int i = 0; i < MAX_MEM_PTR_SIZE; ++i) { if(this->m_mptr[i] < rhs.m_mptr[i]) return -1; if(this->m_mptr[i] > rhs.m_mptr[i]) return 1; } return 0; } template <class T> int functor_compair(const function& rhs) const { if(m_fclass == NULL || rhs.m_fclass == NULL) return normal_compair(rhs); int r = strcmp(m_fclass, rhs.m_fclass); if(r != 0) return r; T& t1 = (*(T*)m_gptr); T& t2 = (*(T*)rhs.m_gptr); if (t1 < t2) return -1; if (t2 < t1) return 1; return 0; }public: // 比较操作, 不需要类型转换, 就不使用全局函数了 bool operator==(const function& rhs) const { return (this->*m_compair)(rhs) == 0; } bool operator<(const function& rhs) const { return (this->*m_compair)(rhs) < 0; } bool operator!=(const function& rhs) const { return (this->*m_compair)(rhs) != 0; } bool operator>(const function& rhs) const { return (this->*m_compair)(rhs) > 0; } bool operator<=(const function& rhs) const { return (this->*m_compair)(rhs) <= 0; } bool operator>=(const function& rhs) const { return (this->*m_compair)(rhs) >= 0; }}; // end classusing namespace std;class Person{public: Person(void) { m_pValue = new int; *m_pValue = 1; } ~Person(void) { cout <<"~Person"<<endl; delete m_pValue; m_pValue = NULL; };public: void SayHello(int) { cout << "hello , i am a person. this:" <<this<<" value :"<<*m_pValue<<endl; }private: int* m_pValue;};void SayHelloFromGlobal(int){ cout << "hello, i am a global fun." << endl;}class SayHelloFunctor{public: SayHelloFunctor(int xx = 0) : x(xx) {}; void operator()(int) { cout << "hello, functor with ." << x << endl; } bool operator<(const SayHelloFunctor& rhs) const { return x < rhs.x; }private: int x;};int main(){ Person p1, p2; SayHelloFunctor fr1(1), fr2(2), fr3(2); typedef function<void (int)> myfunction; myfunction f1 = myfunction(&SayHelloFromGlobal); myfunction f2 = myfunction(&p1, &Person::SayHello); myfunction f3 = myfunction(&p2, &Person::SayHello); myfunction f4 = myfunction(&p1, &Person::SayHello); cout << (f1 == f2) << endl; cout << (f2 == f3) << endl; cout << (f2 == f4) << endl; myfunction ff1 = myfunction(&fr1); myfunction ff2 = myfunction(&fr2); myfunction ff3 = myfunction(&fr3); myfunction ff4 = myfunction(&fr1); cout << (f1 == ff1) << endl; cout << (ff1 == f1) << endl; // 和上一个比较执行流程不同 cout << (ff1 == ff2) << endl; cout << (ff2 == ff3) << endl; cout << (ff1 == ff3) << endl; f1(0); f2(0); f3(0); f4(0); ff1(0); ff2(0); ff3(0); ff4(0);}