Я должен создать очень ХАШНУЮ карту хеш-указателей функций. Мое требование — просто добавить значения в него, а затем получить его на основе ключа. По какой-то политической причине я не могу использовать какую-либо стандартную библиотеку. У меня есть код, который отлично работает. Но если я хочу указатели функций на мои функции класса, то это не сработает. Любое предложение, что должно быть модификацией в коде ниже.
При этом PING и REFRESH являются независимыми функциями. Так что этот код работает. Но если я перенесу эти функции в класс HashMap, то произойдет сбой.
Код:—
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <iomanip>
using namespace std;
typedef void (*FunctionPtr)();
void ping(){
cout<<"ping";
}
void refresh(){
cout<<"refresh";
}
class HashEntry {
private:
int key;
FunctionPtr func_ptr1;;
public:
HashEntry(int key, FunctionPtr fptr) {
this->key = key;
this->func_ptr1 = fptr;
}
int getKey() {
return key;
}
FunctionPtr getValue() {
return this->func_ptr1;
}
};
const int TABLE_SIZE = 128;
class HashMap {
private:
HashEntry **table;
public:
HashMap() {
table = new HashEntry*[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++)
table[i] = NULL;
}
FunctionPtr get(int key) {
int hash = (key % TABLE_SIZE);
while (table[hash] != NULL && table[hash]->getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
if (table[hash] == NULL)
return NULL;
else
return table[hash]->getValue();
}
void put(int key, FunctionPtr fptr) {
int hash = (key % TABLE_SIZE);
while (table[hash] != NULL && table[hash]->getKey() != key)
hash = (hash + 1) % TABLE_SIZE;
if (table[hash] != NULL)
delete table[hash];
table[hash] = new HashEntry(key, fptr);
}
~HashMap() {
for (int i = 0; i < TABLE_SIZE; i++)
if (table[i] != NULL)
delete table[i];
delete[] table;
}
};void main(){
HashMap* pHashsMap = new HashMap();
pHashsMap->put(1,ping);
pHashsMap->put(2,refresh);
pHashsMap->put(3,ping);
pHashsMap->put(4,refresh);
pHashsMap->put(5,ping);
pHashsMap->put(6,refresh);
cout<<" Key 1---"<<pHashsMap->get(1)<<endl;
pHashsMap->get(1)();
cout<<" Key 5---"<<pHashsMap->get(5)<<endl;
pHashsMap->get(5)();
cout<<" Key 3---"<<pHashsMap->get(3)<<endl;
pHashsMap->get(3)();
cout<<" Key 6---"<<pHashsMap->get(6)<<endl;
pHashsMap->get(6)();
delete pHashsMap;
}
Смарт-Alec ответ: проверить код для std::bind
учитесь на нем и создавайте свои собственные (хотя tbh, не использующий STL / boost не умен …).
более простой ответ: вам нужно создать объединенный тип для хранения обычного указателя на функцию и указателя на функцию-член класса, а затем сохранить bool, чтобы указать, является ли он указателем класса:
class funcbind_t
{
union
{
void (*pf)();
void (SomeClass::*mfp)();
};
bool member;
funcbind_t(void (*_pf)()) : pf(_pf), member(false)
{
}
funcbind_t(void (SomeClass::*_mpf)()) : mpf(_mpf), member(true)
{
}
void operator ()()
{
if(member)
mfp();
else
fp();
}
};
как вы можете видеть, это станет грязным, когда вы начнете нуждаться в различных параметрах для функций.
Других решений пока нет …