Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: AgeR en 28 de Octubre de 2003, 05:10:47 PM

Título: Duda Sobre Singletons
Publicado por: AgeR en 28 de Octubre de 2003, 05:10:47 PM
 Pues tengo una duda sobre el uso de los singletons.
Vamos a ver, por ejemplo tengo una clase para generar logs y la he hecho de tipo singleton.
Dentro de otra clase, por ejemplo la que me maneja los gráficos, tengo un miembro de tipo Log.
Lo normal sería para, por ejemplo, escribir algo en el log hacer lo siguiente :
Log->ObtenInstancia()->Escribir("loquesea");

Ahora bien, no sería más cómodo hacer al crear la clase que use el log lo siguiente?
Log = Log->ObtenInstancia();

Después para escribir...
Log->Escribir("loquesea");

De hecho lo estoy haciendo de esta última forma y parece funcionar bien, pero por si acaso...
Hay algo que me he pasado por alto? Puede surgir algún problema o es así como suele hacerse?
Hmmm no estoy muy seguro de haber pillado la utilidad y uso de los singletons  (nooo)

Gracias!
---
Vale, creo que acabo de pillar algo XD
Vamos, que no hace falta que meta ningún miembro de tipo Log, con hacer CLog::ObtenInstancia() funcionaría (siempre que incluya la cabecera donde está la clase declarada).
Parece que lo normal sería hacer un #define Log CLog::ObtenInstancia() para no poner todo el chorrotón cada vez que quiera usarlo. Estoy en lo cierto?  (uoh)
Título: Duda Sobre Singletons
Publicado por: sés en 28 de Octubre de 2003, 05:31:57 PM
 No sé, a mí me parece mejor tu forma. Yo siempre hago las cosas así.

El único problema podría ser que "ObtenInstancia()" hiciera algo más y pudiera dar punteros diferentes entre llamadas. Pero si esa clase es tuya, y sabes que no hace nada extraño, no le veo el problema.
Título: Duda Sobre Singletons
Publicado por: CoLSoN2 en 28 de Octubre de 2003, 08:29:45 PM
 que has creado un objeto de tipo Log? si es una clase singleton no deberias ni poder hacer eso.
de toda la vida se han usado singleton con constructor privado, para evitar eso.
¿qué como lo creas entonces?
pues tienes tu clase:

class A {
Singleton();
~Singleton();
public:
static A &getSingleton() {
          static A;
          return A;
}
[...]
};


y luego para usarlo pues

A::getSingleton().blabla(..);


si estoy metiendo la zarpa vilmente que alguien me corrija, pero creo que estoy en lo cierto
Título: Duda Sobre Singletons
Publicado por: Zaelsius en 28 de Octubre de 2003, 08:40:54 PM
 Creo que Ager quiso decir:

pLog = Log::ObtenInstancia();

Edit: Joer acabo de ver el edit de Ager XD

Yo me refería a que a veces hago cosas del estilo de:

FunciónDeNoSeQué()
{

Graphics* pGraphics = Graphics::GetInstance();

pGraphics->Noseque();
pGraphics->talycual();


}


Aunque nunca he comparado el código generado para los dos casos(el mio y el de Ager, entiéndase).. es probable que no sea más eficiente que llamar a GetInstance() cada vez, pero a nivel de código queda algo más limpio que una macro.
Título: Duda Sobre Singletons
Publicado por: AgeR en 28 de Octubre de 2003, 08:42:16 PM
 Hmmm a ver, dentro de una clase que vaya a usar el log creo :

CLog *Log;


Cuando inicializo la clase, no "creo" un nuevo objeto de la clase CLog, lo que hago es lo siguiente :

Log = Log->ObtenInstancia();


Aunque viéndolo así quizá ahora me parece más correcto usar :

Log = CLog::ObtenInstancia();


El constructor del log no lo toco para nada  :ph34r:
Pero como ya digo, no sé mucho del tema de singletons, de ahí el pedir ayuda.

Título: Duda Sobre Singletons
Publicado por: Zaelsius en 28 de Octubre de 2003, 08:45:52 PM
 A ver si nos sincronizamos XDDDD

Edit: Ager tio pon un "m_ " a las variables miembro que si no aquí nos vamos a volver locos XDDD.

5º o 6º reedit(he perdio la cuenta): Ya podias haber puesto "m_pLog" desde un principio, k de ahí a "Log" hay un buen trecho :rolleyes:

Reeeeedit:
El peligro de guardar un puntero permanente a una clase singleton, es que a priori desconocemos cuando será destruido el singleton.

Sí, ya sé que cada uno sabe perfectamente como va su propio engine y el orden de destrucción de sus instancias globales, pero eso disminuye la independencia de las partes del sistema, al tener que saber en qué orden se destruye cada componente del sistema. Bla bla.  
Título: Duda Sobre Singletons
Publicado por: AgeR en 28 de Octubre de 2003, 09:16:13 PM
Cita de: "ZaelSiuS"Edit: Ager tio pon un "m_ " a las variables miembro que si no aquí nos vamos a volver locos XDDD.

5º o 6º reedit(he perdio la cuenta): Ya podias haber puesto "m_pLog" desde un principio, k de ahí a "Log" hay un buen trecho :rolleyes:
:rolleyes: Estoooooo perdón, tengo todas las clases bien escritas menos la de log  (nooo) .

Bueno, entonces parece que

m_pLog = CLog::ObtenInstancia();


es lo correcto.

Hmmm bueno, en mi engine todos los singletons que tengo previsto usar se crean al crear el engine, y no se destruyen hasta que no se destruye el engine, así que con un poco de cuidado no debería haber problema. Pero bueno, obviamente no parece la mejor solución...

Gracias por las respuestas, parece que lo voy pillando  (uoh)  
Título: Duda Sobre Singletons
Publicado por: tiutiu en 02 de Noviembre de 2003, 02:17:00 PM
 ZaelSius lo ha dicho to bien xD
La finalidad del singleton es evitar q no se haga mas d una instancia de una clase. Entonces puedes hacer lo q t de la gana mientras no instancies. Si tu clase se llama CLog, entonces tenemos lo siguiente:


CLog::GetInstance()->metodo();


CLog *pLog = CLog::GetInstance();
pLog->metodo();

Estos son los 2 usos posibles q le veo ahora, aunq variara segun implementes el singleton. El segundo no crea ninguna instancia, simplemente mete el puntero en una variable para no tener q escribir tanto codigo.

Para el logger casi q con la primera manera ya vale, yo la segunda la uso por ejemplo para cuando cargo mogollon d modelos o texturas.
Título: Duda Sobre Singletons
Publicado por: NaiL en 18 de Noviembre de 2003, 02:44:50 PM
 Wenas.. mientras leia westros comentarios.. pense ke dada la naturaleza de un sigleton..
si quereis poner una referencia al singleton dentro de otra clase.. para mejorar la visivilidad del codigo
quizas seria mas acertado declararlo como

class X
{
public:
  const static CLog* pLog = CLog::GetInstance();
  ...
...
}


edit:
obiamente teniendo en cuenta ke la vida del sigleton cubre la vida de los  objetos de la clase X, en caso contrario seria mejor ke el codigo fura un poko mas "confuso".
Título: Duda Sobre Singletons
Publicado por: Zaelsius en 18 de Noviembre de 2003, 03:07:45 PM
 Briconsejo: Si intentas compilar ese código, verás que no te deja.

Sólo se podría inicializar fuera de la declaración de clase, en el .cpp. Tipo:

const CLog* X::pLog = CLog::GetInstance();


Y como dices en el edit, tratándose de este caso particular(singletones), es muy difícil hacer que funcione sin saber el orden de construcción de los singletones..
Título: Duda Sobre Singletons
Publicado por: AgeR en 18 de Noviembre de 2003, 04:20:08 PM
 Bueno, pues gracias a todos. Ya tengo los singletons funcionando a la perfección. El caso es que estoy terminando un motor 2D (por llamarlo de alguna manera...) y ya que lo tengo casi terminado me he planteado hacer un mínimo de documentación y sacarlo por si alguien quiere usarlo.
Pero... los singletons se llevan bien con las dll?
Explico : El "motor" está dividido en diversas partes, y todas ellas son singletons. Está la clase motor, y dentro de esta hay una para graficos (resolución, color de fondo, etc.), otra para recursos (sprites, sonidos...), otra para input...

Habrá problemas al crear y/o usar los singletons de este modo?
Convendría más crear una librería estática en vez de la dll en este caso?

De nuevo, gracias por todo!
Título: Duda Sobre Singletons
Publicado por: NaiL en 18 de Noviembre de 2003, 09:22:11 PM
 
Citar
Sólo se podría inicializar fuera de la declaración de clase, en el .cpp. Tipo:

const CLog* X::pLog = CLog::GetInstance();


Estas seguro? justamente los const static solo se pueden inicializar en la clase.. pero weno no intente compilar nada parecido.

PD: si fuera const se inicializaria en el constructor. no?
Título: Duda Sobre Singletons
Publicado por: Zaelsius en 18 de Noviembre de 2003, 09:29:11 PM
 Sí, estoy seguro  :P . Los únicos tipos que se pueden inicializar en la declaración de clase son los "const static integrales"(al menos en Visual Studio). Los tipos integrales son int, char, etc. Tampoco vale int*, p.ej.
Título: Duda Sobre Singletons
Publicado por: NaiL en 18 de Noviembre de 2003, 10:21:29 PM
 ke kurioso.. weno weno tomo nota :P