最近、本「Modern C++ design」に従って、2 つのテンプレート クラスを作成しました。これらのクラスは便利だと思いますが、私の会社の誰も私に同意しません。
1 つ目はパラメーター ラッパーで、関数パラメーターを単一の動的オブジェクトにパッケージ化できます。「モダン 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);
2 つ目は一般的なコールバック ラッパーで、他のラッパーと比較していくつかの特別な点
があります。
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();
}