Я хочу сохранить массив функций-членов разных классов. Просто повторение здесь:C++ :: Array of Member Functions
Требования:
- TYPEOF класса
- Экземпляр класса, содержащий функцию
- AddressOf функции члена функции
- членам параметры
Что я могу хранить:
- Экземпляр класса, содержащий функцию
- AddressOf функция член. Функция
- член параметры
Как правило, вам не нужно хранить тип класса вообще, так как вы можете сделать указатель массива к типу класса. Причина, по которой я не могу этого сделать, состоит в том, что типы классов, которые я принимаю, неизвестны и различны. Класс будет использоваться во многих разных проектах, где типы классов неизвестны.
Мне нужно хранить различные типы классов в массиве/списке, и в этом случае я просто сохранил адреса классов в указателе массива.
Моя проблема: Когда я собираюсь вызвать функцию-член, мне нужно отнести класс-класс к типу класса, но я не знаю, к какому типу нужно приложить.
Пример кода (не проверено - написано в режиме реального быстро):
class A
{
public:
void test1(int i);
};
class B
{
public:
void test2(char c);
};
class Container
{
long* objects;
long* funcs;
int index;
public:
Container()
{
objects = new long[5];
funcs = new long[5];
index = 0;
}
template <class C, typename Types ...>
void Add(C *obj, void (C::*func)(Types ...))
{
objects[index++] = (long)obj;
funcs[index++] = (long)func;
}
typename <Types ...>
void Call(int inx, Types ... values)
{
void (*func)(Types ...) = (void (*)(Types ...))funcs[inx];
// This is where I've got trouble. I don't store the Class
// types, so I don't know what pointer Class type to cast
// the Class Instance address to.
(((*???)objects[inx])->*func)(values ...);
}
};
Спасибо заранее. Спросите заранее, есть ли какие-либо дыры или какие-либо вопросы.
Что заставляет вас думать, что 'funcs [index ++] = (long) func;' действительно? Если я не ошибаюсь, вы применяете функцию указателя к члену в 'long'. Это незаконно. –
На ubuntu-15.04, gcc 4.9, указатель для метода класса составляет 10 байтов. Я был очень удивлен. Таким образом, ни void *, ни long * не являются достаточными, чтобы указать на метод. Найдено подтверждение, что оно может быть больше, чем void * в SO. –