У меня есть C ++ singleton-фабричный класс под названием MemMgr, который отвечает за управление кучей памяти для объектов в библиотеке:
#include <vector>
class MemMgr
{
public:
// Callback interface of functions to register with MemMgr
typedef size_t (*MemSizeFunc)(void);
void Register(MemSizeFunc memSizeFunc);
static MemMgr & GetInst(void);
// more public functionality related to managing memory
private:
// a vector (not a map) of functions pointers to keep track of
std::vector<MemSizeFunc> m_memSizeFuncs;
MemMgr(void);
MemMgr(MemMgr const &);
MemMgr & operator= (MemMgr const &);
// more private functionality related to managing memory
};
Я хотел бы иметь возможность иметь объекты любых классов, которые хотели бы использовать управляемую память, иметь возможность регистрироваться в MemMgr через (нестатическая) функция-член, которая будет вычислять и возвращать объем управляемой памяти, который необходим конкретному объекту. Что-то вроде следующего:
class MemMgrUser
{
public:
MemMgrUser(void)
{
MemMgr::GetInst().Register(GetManagedMemSize);
}
private:
size_t GetManagedMemSize(void)
{
// calculations involving member variables
}
};
(Затем, до того, как MemMgr фактически выделит какую-либо память, он запросит зарегистрированные для нее функции, связанные с размером, чтобы определить объем выделяемой памяти.)
Тем не менее, компилятор кричит на меня, когда я пытаюсь использовать описанный выше подход, потому что я пытаюсь зарегистрировать указатели на функции-члены, а не на обычные указатели функций.
Есть ли у кого-нибудь предложения о том, как я мог бы реализовать такую функциональность? У меня проблемы с просмотром, как реализация шаблона (или полиморфная) будет реализована.
Спасибо,
Аарон
Вы даже не пытаетесь зарегистрировать указатель на функцию-член. Это должно быть указано как &MemMgrUser::GetManagedMemSize
, Вы не можете использовать простое имя функции-члена, кроме как в выражении, которое ее вызывает.
Но даже если у вас был указатель на функцию-член, его нельзя использовать так же, как обычный указатель на функцию с той же очевидной сигнатурой. Вызов функции-члена всегда требует, чтобы объект вызывал ее. this
указатель, доступный в функции, является дополнительным скрытым параметром.
Если вы можете использовать функции стандартной библиотеки C ++ 11, вы можете typedef std::function<size_t (void)> MemSizeFunc;
вместо текущего typedef. Это позволяет хранить различные виды функций и функциональных объектов, которые можно вызывать с этой подписью, как MemSizeFunc
, В частности, вы можете зарегистрировать свой GetManagedMemSize
функция-член связана с подходящим MemMgrUser
объект, например как:
MemMgrUser()
{
MemMgr::GetInst().Register(std::bind(&MemMgrUser::GetManagedMemSize, *this));
}
Других решений пока нет …