Eliminando o codigo Fanfarrão

18 02 2008

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…