C++ 参考等级第2部分
,看起来我没有提供足够的细节 我有一个名为C++ 参考等级第2部分,c++,templates,function-pointers,C++,Templates,Function Pointers,,看起来我没有提供足够的细节 我有一个名为CallbackObject的对象,它被设计为包含一个对象实例、要调用的函数的信息以及在调用时要传递的参数 template <typename objectType, typename memberFunctionPtrType, typename memberFcnArg1Type> struct CallbackObject1 { objectType obj ; memberFuncti
CallbackObject
的对象,它被设计为包含一个对象实例、要调用的函数的信息以及在调用时要传递的参数
template <typename objectType,
typename memberFunctionPtrType,
typename memberFcnArg1Type>
struct CallbackObject1
{
objectType obj ;
memberFunctionPtrType fcnPtr ;
memberFcnArg1Type arg1 ;
CallbackObject1(objectType iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
obj = iObj ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
void exec()
{
(obj.*fcnPtr)( arg1 ) ;
}
} ;
但这充其量是粗糙的,最坏情况下是难以使用的,如果其他人正在使用此代码,那么如果使用的对象类型实际上是指针,他们将不得不创建不同类型的回调对象
有什么办法可以解决这个问题吗?将多态函数对象(如
boost::function
)与生成函数(如boost::bind
)结合使用。这是一个非常优秀的解决方案——天才发生在生成函子时,而不是调用函子时,任何可以使用正确签名调用的函数对象都可以被调用。好的,在I get上应用“重载”方法
模板
结构CallbackObject1:公共回调
{
对象类型obj;
objectType*pObj;
memberFunctionPtrType fcnPtr;
成员Fcnarg1类型arg1;
CallbackObject1(对象类型iObj,
memberFunctionPtrType iFcnPtr,
成员FCNARG1类型(iArg1)
{
obj=iObj;
pObj=0;
fcnPtr=iFcnPtr;
arg1=iArg1;
}
CallbackObject1(对象类型*iObj,
memberFunctionPtrType iFcnPtr,
成员FCNARG1类型(iArg1)
{
pObj=iObj;
fcnPtr=iFcnPtr;
arg1=iArg1;
}
void exec()
{
if(pObj)
(pObj->*fcnPtr)(arg1);
其他的
(obj.*fcnPtr)(arg1);
}
} ;
使用
typedef void(点::*PointPrintFcnType)(int);
p点;
p、 x=p.y=1;
CallbackObject1 ocall(p,&Point::print,5);
ocall.exec();
CallbackPObject1 ocallP(&p,&Point::print,2);
ocallP.exec();
它工作正常,但内部不像我希望的那样干净。下面是一个示例帮助函数,假设为void return,一个参数,并且不需要处理多个间接级别:
template <typename T, typename F, typename A>
inline void invoke(T& obj, F func, const A& arg)
{
(obj.*func)(arg);
}
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
(obj->*func)(arg);
}
第一个问题中提供的任何答案都是有效的,包括部分专门化(您的第二个类可能是第一个类的部分专门化)和使用重载函数作为帮助函数来实际执行调用。它们对类如何工作?完全相同。您的问题是很难在
exec()
中编写表达式。如果您使用Johannes或my answer,它提供了一个helper函数,您可以使用该函数在exec()
中编写该语句。所说的helper函数可以是全局函数或私有成员函数。是的,编写exec()很困难。我写了一个if语句,见下面我的答案。你还能写exec吗?我也试过了boost::bind
,它很酷,但我想这样做。如果这听起来像强迫症,很抱歉,但我不想使用boost::function来解决这个特定的问题
template <typename pObjectType,
typename memberFunctionPtrType,
typename memberFcnArg1Type>
struct CallbackPObject1
{
pObjectType obj ;
memberFunctionPtrType fcnPtr ;
memberFcnArg1Type arg1 ;
CallbackPObject1(pObjectType iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
obj = iObj ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
void exec()
{
(obj->*fcnPtr)( arg1 ) ;
}
} ;
template <typename objectType,
typename memberFunctionPtrType,
typename memberFcnArg1Type>
struct CallbackObject1 : public Callback
{
objectType obj ;
objectType *pObj ;
memberFunctionPtrType fcnPtr ;
memberFcnArg1Type arg1 ;
CallbackObject1(objectType iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
obj = iObj ;
pObj = 0 ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
CallbackObject1(objectType *iObj,
memberFunctionPtrType iFcnPtr,
memberFcnArg1Type iArg1 )
{
pObj = iObj ;
fcnPtr = iFcnPtr ;
arg1 = iArg1 ;
}
void exec()
{
if( pObj )
(pObj->*fcnPtr)( arg1 ) ;
else
(obj.*fcnPtr)( arg1 ) ;
}
} ;
typedef void (Point::* PointPrintFcnType)( int ) ;
Point p ;
p.x=p.y=1;
CallbackObject1<Point, PointPrintFcnType, int> ocall( p, &Point::print, 5 );
ocall.exec() ;
CallbackPObject1<Point*, PointPrintFcnType, int> ocallP( &p, &Point::print, 2 );
ocallP.exec() ;
template <typename T, typename F, typename A>
inline void invoke(T& obj, F func, const A& arg)
{
(obj.*func)(arg);
}
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
(obj->*func)(arg);
}
template <typename T, typename F, typename A>
inline void invoke(T* obj, F func, const A& arg)
{
invoke(*obj, func, arg);
}
void exec()
{
invoke(obj, fcnPtr, arg1);
}