Я пытаюсь создать универсальный объект обратного вызова, который будет содержать произвольные данные и вызывать функции-члены связанных классов.Из-за внутренней политики я не могу использовать Boost.
Объект обратного вызова выглядит следующим образом:
template<typename Object, typename Data>
class Callback
{
public:
typedef void (Object::*PHandler)(Callback*);
Callback(Object* obj, PHandler handler) : pObj(obj), pHandler(handler) {}
Callback& set(PHandler handler) { pHandler = handler; return *this; }
void run() { (pObj->*pHandler)(this); }
public:
Data data;
protected:
Object* pObj;
PHandler pHandler;
};
И класс, на котором он работает:
struct Object1
{
struct Data { int i; };
typedef Callback<Object1, Data> Callback1;
void callback(Callback1* pDisp) { printf("%cb\n", pDisp->data.i); }
void test()
{
Callback1 cb(this, &Object1::callback);
cb.data.i = 1;
cb.run();
}
};
СледующееТест работает, как и ожидалось:
Object1 obj1;
obj1.test();
Пока все хорошо.
Однако, когда коллега попытался унаследовать класс Callback
вместо использования typedef
, он получил компиляциюошибки из-за несовместимых указателей:
struct Object2
{
struct Data { int i; Data(int j) { i = j; } };
class Callback2 : public Callback<Object2, Data>
{
Callback2(Object2* obj, PHandler handler, int i) : Callback(obj, handler) { data.i = i; }
};
void callback(Callback2* pDisp) { printf("%cb\n", pDisp->data.i); }
void test()
{
Callback2 cb(this, &Object2::callback, 2);
cb.run();
}
};
Я пытался использовать «любопытно повторяющийся шаблон шаблона» в классе Callback и смог заставить работать производные классы, но он сломал код, который использовал метод typedef
.
Мой вопрос:
Как я могу изменить класс Callback
для работы с обоими случаями и без необходимости дополнительной работы со стороны пользователякласса?