最近我根据“Modern C++ design”一书制作了两个模板类。我认为这些课程很有用,但我公司里没有人同意我的观点,那么有人能告诉我这些东西是否有用吗?
第一个是参数包装器,它可以将函数参数包装到单个动态对象中。它看起来像“现代C++设计”中的TypeList。
你可以像这样使用它:
您的代码的某个地方:
int i = 7;
bool b = true;
double d = 3.3;
CParam *p1 = CreateParam(b,i);
CParam *p2 = CreateParam(i,b,d);
您的代码的其他地方:
int i = 0;
bool b = false;
double d = 0.0;
GetParam(p1,b,i);
GetParam(p2,i,b,d);
第二个是通用回调包装器,它与其他包装器相比有一些特别之处:
1.这个模板类有一个动态基类,它可以让你使用一个单一类型的对象来代表所有的包装器对象。
2.它可以将回调和它的参数一起包装,你可以稍后执行回调和参数。
你可以像这样使用它:
您的代码的某处:
void Test1(int i)
{
}
void Test2(bool b,int i)
{
}
CallbackFunc * p1 = CreateCallback(Test1,3);
CallbackFunc * p2 = CreateCallback(Test2,false,99);
您的代码的其他地方:
p1->Excute();
p2->Excute();
以下是部分代码:
参数包装器:
class NullType;
struct CParam
{
virtual ~CParam(){}
};
template<class T1,class T2>
struct CParam2 : public CParam
{
CParam2(T1 &t1,T2 &t2):v1(t1),v2(t2){}
CParam2(){}
T1 v1;
T2 v2;
};
template<class T1>
struct CParam2<T1,NullType> : public CParam
{
CParam2(T1 &t1):v1(t1){}
CParam2(){}
T1 v1;
};
template<class T1>
CParam * CreateParam(T1 t1)
{
return (new CParam2<T1,NullType>(t1));
}
template<class T1,class T2>
CParam * CreateParam(T1 t1,T2 t2)
{
return (new CParam2<T1,T2>(t1,t2));
}
template<class T1,class T2,class T3>
CParam * CreateParam(T1 t1,T2 t2,T3 t3)
{
CParam2<T2,T3> t(t2,t3);
return new CParam2<T1,CParam2<T2,T3> >(t1,t);
}
template<class T1>
void GetParam(CParam *p,T1 &t1)
{
PARAM1(T1)* p2 = dynamic_cast<CParam2<T1,NullType>*>(p);
t1 = p2->v1;
}
回调包装器:
#define PARAM1(T1) CParam2<T1,NullType>
#define PARAM2(T1,T2) CParam2<T1,T2>
#define PARAM3(T1,T2,T3) CParam2<T1,CParam2<T2,T3> >
class CallbackFunc
{
public:
virtual ~CallbackFunc(){}
virtual void Excute(void){}
};
template<class T>
class CallbackFunc2 : public CallbackFunc
{
public:
CallbackFunc2():m_b(false){}
CallbackFunc2(T &t):m_t(t),m_b(true){}
T m_t;
bool m_b;
};
template<class M,class T>
class StaticCallbackFunc : public CallbackFunc2<T>
{
public:
StaticCallbackFunc(M m):m_m(m){}
StaticCallbackFunc(M m,T t):CallbackFunc2<T>(t),m_m(m){}
virtual void Excute(void){assert(CallbackFunc2<T>::m_b);CallMethod(CallbackFunc2<T>::m_t);}
private:
template<class T1>
void CallMethod(PARAM1(T1) &t){m_m(t.v1);}
template<class T1,class T2>
void CallMethod(PARAM2(T1,T2) &t){m_m(t.v1,t.v2);}
template<class T1,class T2,class T3>
void CallMethod(PARAM3(T1,T2,T3) &t){m_m(t.v1,t.v2.v1,t.v2.v2);}
private:
M m_m;
};
template<class M>
class StaticCallbackFunc<M,void> : public CallbackFunc
{
public:
StaticCallbackFunc(M method):m_m(method){}
virtual void Excute(void){m_m();}
private:
M m_m;
};
template<class C,class M,class T>
class MemberCallbackFunc : public CallbackFunc2<T>
{
public:
MemberCallbackFunc(C *pC,M m):m_pC(pC),m_m(m){}
MemberCallbackFunc(C *pC,M m,T t):CallbackFunc2<T>(t),m_pC(pC),m_m(m){}
virtual void Excute(void){assert(CallbackFunc2<T>::m_b);CallMethod(CallbackFunc2<T>::m_t);}
template<class T1>
void CallMethod(PARAM1(T1) &t){(m_pC->*m_m)(t.v1);}
template<class T1,class T2>
void CallMethod(PARAM2(T1,T2) &t){(m_pC->*m_m)(t.v1,t.v2);}
template<class T1,class T2,class T3>
void CallMethod(PARAM3(T1,T2,T3) &t){(m_pC->*m_m)(t.v1,t.v2.v1,t.v2.v2);}
private:
C *m_pC;
M m_m;
};
template<class T1>
CallbackFunc *CreateCallback(CallbackFunc *p,T1 t1)
{
CParam2<T1,NullType> t(t1);
return new StaticCallbackFunc<CallbackFunc *,CParam2<T1,NullType> >(p,t);
}
template<class C,class T1>
CallbackFunc *CreateCallback(C *pC,void(C::*pF)(T1),T1 t1)
{
CParam2<T1,NullType>t(t1);
return new MemberCallbackFunc<C,void(C::*)(T1),CParam2<T1,NullType> >(pC,pF,t);
}
template<class T1>
CParam2<T1,NullType> CreateCallbackParam(T1 t1)
{
return CParam2<T1,NullType>(t1);
}
template<class T1>
void ExcuteCallback(CallbackFunc *p,T1 t1)
{
CallbackFunc2<CParam2<T1,NullType> > *p2 = dynamic_cast<CallbackFunc2<CParam2<T1,NullType> > *>(p);
p2->m_t.v1 = t1;
p2->m_b = true;
p->Excute();
}