Certo dia estava lendo a Easy2D, e vi uma maneira Interessante, mais não desconhecida de implementar o padrão Singleton usando o std::auto_ptr. Eu já havia me deparado com um problema ao implementar uma classe Singleton, usando os ponteiros compartilhados da boost (boost::shared_ptr) que é semelhate à std::auto_ptr porem com mais recursos., mais o compilador acusava um erro, pois o destrutor da singleton era protected, eu não poderia deixar o destrutor publico, pois qualquer um podia destruilo e minha instancia da singleton retornaria nulo, Então descobri que podederia passar um segundo parametro no construtor ou no metodo reset do shared_ptr, esse segundo parametro era o Deleter, uma classe especial para deletar o ponteiro (na verdade usava apenas o operador () da classe)., então crie uma classe generica usando template chamada Deleter e à declarava como friend da Singleton, sua implementação ficou assim
template <class T>
class Deleter
{
public:
void operator()(T* ptr)
{
if (ptr != NULL) {
delete ptr;
ptr = NULL;
}
}
};
Eu achava perfeito, e ainda podia usar nos for_each da vida, porém ainda era POG…
Uma noite, bebendo e ouvindo musica (metal!), lembrei das magicas que std::mem_fun podia fazer, e resolvi implementa-la, a cobaia foi a classe InputManager da Wintermoon, usando o metodo teardown de Mouse e Keyboard como Deleter
InputManager::Init()
{
// ...
mKeyboard = boost::shared_ptr<Keyboard> (new Keyboard,
std::mem_fun(&Keyboard::teardown));
mMouse = boost::shared_ptr<Mouse> (new Mouse,
std::mem_fun(&Mouse::teardown));
}
InputManager::Shut()
{
// reset é um membro de shared_ptr, responsavel
// por liberar a memoria do ponteiro
mKeyboard.reset();
mMouse.reset();
}
// class Mouse
void Mouse::teardown()
{
// clean up data...
}
// class Keyboard
void Keyboard::teardown()
{
// clean up data...
}
E não é que funcionou, o codigo ficou muito mais claro, mais ainda não acabou, ainda não crie a classe Singleton dos meus sonhos, usando shared_ptr, volatile, template, NonCopyable, mais estou no caminho…
