C++

Eliminando o codigo Fanfarrão

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 deletar a instancia da singleton retornaria nulo, Então descobri que poderia passar um segundo parâmetro no construtor ou no método reset do shared_ptr, esse segundo parâmetro era o Deleter, uma classe especial para deletar o ponteiro (na verdade usava apenas o operador () da classe)., então crie uma classe genérica usando template chamada Deleter e à declarava como friend da Singleton, sua implementação ficou assim

C++
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 método teardown de Mouse e Keyboard como Deleter

C++
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));
}
C++
InputManager::Shut()
{
    // reset é um membro de shared_ptr, responsavel
    // por liberar a memoria do ponteiro
    mKeyboard.reset();
    mMouse.reset();
}
C++
// class Mouse

void Mouse::teardown()
{
    // clean up data...
}
C++
// class Keyboard

void Keyboard::teardown()
{
    // clean up data...
}

E não é que funcionou, o código 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…

Fonte arquivística

Conteúdo recuperado via Wayback Machine, captura 20080528111125.

Abrir registro original ↗

Este mesmo post já existia no antecessor skhaz.wordpress.com. A cópia foi unida a este registro canônico, sem publicar um post duplicado.

Abrir captura da fase WordPress.com ↗

Discussão preservada

3 comentários

  1. DarkSasori

    Isso ai….abaixo ao POG….
    apesar q eu ainda uso muito pog por falta de conhecimento :(
    mais isso a gente resolver estudando

    T++

  2. vinigodoy

    Eu vejo poucas vantagens em limpar um Singleton, exceto claro, se ele for MUITO pesado. Como o singleton restringe o objeto a uma única instância isso é raramente um problema.

    Mas é claro que é MUITO legal conhecer truques como esse, que ainda deixam o código elegante e pouco sujeito à erros.

  3. skhaz

    Valeu!!

    Só explicando… Mouse e Keyboard não são do tipo Singleton, mais só podem ser criadas pela InputManager (construtor e descontrutor são protected e InputManager é “friend” deles, e InputManager é uma singleton porque não faria sentido em ter 2 ou mais copias dela no sistema) ao meu ver o usuario construir essas classes (Keyboard e Mouse, futuramente Joystick), elas são criadas e deletadas automaticamente, acho que não ficou muito claro, eu deveria ter postado mais codigo :/