I wrote a class to contain my objects in it.
The code is:
class objectPool
{
private:
struct itemType_{uint count; void* object;};
std::multimap< std::string, itemType_ > pool_;
public:
template<class T>
bool addItem(std::string key, T*& object)
{
std::multimap< std::string, itemType_ >::iterator
i = pool_.find(key);
if(i != pool_.end())
{
object = (T*)(*i).second.object;
(*i).second.count++;
return true;
}
i = pool_.insert(std::pair<std::string,itemType_>(key, (itemType_){1, NULL}));
object = (T*)(*i).second.object;
return false;
}
template<class T>
bool removeItem(std::string key)
{
std::multimap< std::string, itemType_ >::iterator
i = pool_.find(key);
if(i != pool_.end())
{
if((*i).second.count == 1)
{
//important to call the appropriate destructor
delete ((T*)(*i).second.object);
pool_.erase(i);
}
else
(*i).second.count--;
return true;
}
return false;
}
};
And the test code:
#include "objectPool.h"
class testClass
{
public:
~testClass()
{
// I should get here at least once
std::cout << "I am deleted teehee";
}
};
testClass* test;
objectPool myPool;
int main () {
if(!myPool.addItem<testClass>("baba", test))
{
test = new testClass;
}
myPool.removeItem<testClass>("baba");
}
For some reason my test object’s destructor does not want to be invoked.
First questcha: Why? Where I am wrong?
The sec.: Should I use auto_ptr instead? (Although I want to avoid using templates…)
The third.: Is there a better(-looking) solution? (with or without using templates)
The fourth.: Is there a way to invoke constructor via void pointer without templates (or without knowing the original type)?
Thanks ahead! 😀
And sorry for my terrific english (not my native language, although…)
You correctly store a NULL into your T* reference, but that is a reference to the local variable. When you later update that local by calling new, that has no effect on the item stored in the pool.
The easier way to fix this would be to just create the object inside the addItem function using
new T.As for your other question, a way to call the destructor without knowing the original type, there is no way to do that. But there is a trick you can use with templates. You can create a template function like the one below, and then pass around a function pointer to it.
deleter as a simple type which you can typedef and pass around pointers:
To get a pointer to it, just do something like this in your addItem function:
Then later:
You don’t need to know the type of somePtr at the time of deletion, just need to keep a pointer to the deleter. You can also use this method with shared_ptr, which can use a deleter argument.