Olá pessoal, como estamos?
Esse é o primeiro post que estou publicando depois da experiência fantástica que foi o #DNAD11. Aliás, se você não foi, perdeu muita coisa.
Este é um post “curtinho”. Afinal, estou um pouco cansado.
Hoje vou mostrar um exemplo simples de implementação para Singleton em C++.
Esse post é dedicado aos amigos e .
Algumas palavras sobre Singleton
Muitas vezes, é útil garantir que um objeto será instanciado uma única vez e que será acessível globalmente.
Por exemplo, no design de jogos há diversos tipos diferentes de entidades – players, monsters, etc. Também há, normalmente, um “manager” que trata da criação, remoção e gerenciamento de tais objetos. É necessária apenas uma instância desse objeto – um singleton – e é conveniente fazer esse objeto acessível globalmente pois ele deverá ser requisitado em muitos outros objetos.
O padrão Singleton garante essas duas características. Há muitas formas diferentes de implementar este padrão. Entretanto, eu prefiro usar um método estático, Instance(), que retorna um ponteiro para um instância estática da classe.
Alguma controvérsia …
Se você está começando a entender o padrão Singleton e procurar um pouco mais na internet, vai perceber que ele está cercado de “defensores” e “acusadores”.
Isso ocorre porque, na prática, muitas vezes, este pattern não é aplicado adequadamente. Muitas vezes, ele é usado como um recurso “barato” para criar objetos estáticos sem justificativa. Objetos estáticos (globais) podem ser um indicativo de um design pobre.
Sugiro que, antes de usar esse pattern, você entenda bem sua aplicação. Leia os fóruns e artigos. Se instrua! Aproveite bem esse pattern extremamente útil.
Implementando..
Como usual, em C++, construímos um arquivo header (.h) e outro de implementação (.cpp). Comecemos com o header:
#ifndef MY_SINGLETON #define MY_SINGLETON class MySingleton { private: int value; MySingleton(){}; MySingleton(const MySingleton &); MySingleton& operator=(const MySingleton &); public: ~MySingleton(){}; int GetValue() const { return value; } void SetValue(int newValue) { value = newValue; } static MySingleton* Instance(); }; #endif
Como pode perceber, mantive o construtor privado, assim como os construtores associados as operações de cópia e atribuição.
Perceba também que mantive o destrutor público, isso ocorre por que alguns compiladores “implicariam” com uma implementação privada.
O atributo value e os métodos GetValue e SetValue estão aí apenas como exemplos de funcionalidade.
Agora, o .cpp:
#include "MySingleton.h"; MySingleton* MySingleton::Instance() { static MySingleton instance; return &instance; }
Esse código precisa “residir” em um .cpp, pois, de outra forma, uma instância seria criada para cada arquivo onde o header fosse incluído.
A utilização do singleton é muito simples.. Observe:
MySingleton::Instance()->SetValue(10); int num = MySingleton::Instance()->GetValue();
Lindo!
Um pouco de preguiça nunca faz mal…
Sou um “tantin” preguiçoso. Por isso, não gosto muito da ideia de escrever um monte de coisas toda vez que acesso um singleton. Assim, geralmente uso um #define. Observe:
#ifndef MySng #define MySng MySingleton::Instance() #endif
Assim, posso utilizar minha instância de forma menos verbosa. Avalie:
MySng->SetValue(10); int num = MySng->GetValue();
Por hoje, era isso
Posted on junho 6, 2011 by elemarjr
0