Передача указателя метода для нового метода в базовый класс
Я хотел бы иметь возможность вызывать любой произвольный метод (который является универсальным методом), определенный в производном классе от базового класса. Базовый класс не знает о них. Я хотел бы получить этот указатель и смещение виртуальной таблицы и иметь возможность вызывать его. Класс A на самом деле не должен быть базовым, это может быть отдельный класс, который ничего не знает о B, но должен вызывать методы. Является ли это возможным?
class A
{
public:
typedef void (A::*Method)();
void call(Method p)
{
//...
}
};
class B : public A
{
public:
virtual void meth1()
{
}
virtual void meth2()
{
}
virtual void test()
{
call(&TestTask::meth1);
call(&TestTask::meth2);
}
};
Errors:
test.cpp:420:30: error: no matching function for call to ‘B::call(void (TestTask::*)())’
call(&TestTask::meth1);
^
test.cpp:420:30: note: candidate is:
test.cpp:402:10: note: void A::call(A::Method)
void call(Method p)
^
test.cpp:402:10: note: no known conversion for argument 1 from ‘void (TestTask::*)()’ to ‘A::Method {aka void (A::*)()}’
test.cpp:421:30: error: no matching function for call to ‘B::call(void (TestTask::*)())’
call(&TestTask::meth2);
2 ответа
Вы можете использовать шаблон CRTP, чтобы выполнить то, что вы пытаетесь.
template <typename T> struct A
{
typedef void (T::*Method)();
void call(Method m)
{
(static_cast<T*>(this)->*m)();
}
};
struct B : A<B>
{
void meth1(){}
void meth2(){}
void test()
{
call(&B::meth1);
call(&B::meth2);
}
};
Нестатическим функциям-членам необходим объект, на который можно воздействовать, поэтому вы не можете просто вызвать указатель на функцию-член сам по себе. Вы можете определить шаблон для вызова члена любого класса, учитывая объект этого класса:
template <class Class>
void call(Class & c, void (C::*method)()) {
(c.*method)();
}
Если это не то, что вы хотите, то вам нужно уточнить, что вы хотите.