Развернувшись по этому вопросу , похоже, я не предоставил достаточно подробностей.
У меня есть объект с именем 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()
{
<b>(obj.*fcnPtr)( arg1 ) ;</b>
}
} ;
Пример использования:
struct Point
{
float x,y ;
void print( int numTimes )
{
for( int i = 0 ; i < numTimes ; i++ )
printf( "%f %f\n", x, y ) ;
}
} ;
typedef void (Point::* PointPrintFcnType)( int ) ;
int main()
{
Point p ;
p.x=p.y=1;
CallbackObject1<Point, PointPrintFcnType, int> ocall( p, &Point::print, 5 );
ocall.exec() ;
}
Единственная проблема, с которой я сталкиваюсь, это то, что если objectType
является типом указателя, то (obj.*fcnPtr)
терпит неудачу, поскольку он должен действительно прочитать ( (*obj).*fcnPtr)
или (obj->*fcnPtr)
, если obj является указателем.
Теперь у меня есть одно решение, где я определяю другой Класс CallbackObject следующим образом:
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()
{
<b>(obj->*fcnPtr)( arg1 ) ;</b>
}
} ;
Но в лучшем случае это грубовато, а в худшем - трудно использовать, если кто-то еще использует этот код, ему придется создать объект Callback другого типа, если используемый тип объекта на самом деле является указателем.
Есть ли способ обойти это?