Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Singleton vs static

Iniciado por wendal, 21 de Julio de 2006, 11:52:46 AM

« anterior - próximo »

Flint

Cita de: "Pogacha"
Cita de: "Lex"Un singleton se declara así:

class Singleton {
  public:
     static Singleton* Instance();
  protected:
     Singleton();
  private:
     static Singleton* _instance;
};

Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance () {
  if (_instance == 0) {
     _instance = new Singleton;
  }
  return _instance;
}


Para poder usarlo solo tienes que llamar a la función que de devuelve la instancia creada del objeto.
Te falto el delete ... no?

Creo que ésa es precisamente la implementación del Singleton de Gamma. ¿Hay un memory leak? Pues depende de cómo lo mires: un memory leak suele ser definido como una acumulación de datos sobre los que se pierde la referencia durante la ejecución del programa, lo que imposibilita su liberación. En este caso, _instance vive en la memoria hasta que la aplicación termina, por lo que no tiene que considerarse un memory leak. De todos modos, no todos los sistemas operativos liberan la memoria que cuelga de un proceso terminado, por lo que, en esos sistemas, si el singleton hubiera accedido a recursos del sistema, se podría producir un resource leak una vez hubiera finalizado el problema. ¿Solución? Recordarse de hacer un delete sobre el singleton manualmente o cambiar de implementación.

Pablo Zurita

Cada vez que reservas memoria, tenes que liberarla en algún momento antes de salir. No es buena práctica dejar sin liberar porque si por alguna razón decidís modificar cuando tiene que morir tu singleton entonces terminas con un memory leak que es importante. Los programas como DevPartner no definen el "leak on exit" solo para molestarte.

BTW, ninguna de esas implementaciones de singleton son thread-safe.

zupervaca

Es cierto la implementacion que he puesto no es segura en hilos.

Flint

Cita de: "Pablo Zurita"BTW, ninguna de esas implementaciones de singleton son thread-safe.

Efectivamente. Una solución sencilla sería sincronizar el método Instance().

Vicente

Entre singletons anda el juego. Uno en C# que es thread-safe y tiene instanciación perezosa (solo se crea cuando se usa por primera vez):


namespace Test
{
public class Singleton
{
private static readonly Singleton instance = new Singleton();

static Singleton() {}
private Singleton() {}

public static Singleton Instance
{
get { return instance; }
}
}
}


Un saludo!

Vicente

Diferencial

Es interesante, lo unico que no me queda claro es cuando usar la clase Singleton.
Una utilidad que se me acaba de ocurrir es cuando solo quieres tener una instancia de tu programa sin que puedan ejecutarlo dos veces.
Podeis poner los principales motivos de usar singleton o cuando lo usais vosotros?
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

Flint

Cita de: "Diferencial"Es interesante, lo unico que no me queda claro es cuando usar la clase Singleton.
Una utilidad que se me acaba de ocurrir es cuando solo quieres tener una instancia de tu programa sin que puedan ejecutarlo dos veces.
Podeis poner los principales motivos de usar singleton o cuando lo usais vosotros?

Siguiendo estrictamente la definición, cuando quieras asegurar que una instancia de una determinada clase sea la única existente en el programa, quieras tener acceso global a ella, y tener una única variable corriente no te resulte suficiente o apropiado; desde luego es algo dependiente de la aplicación. Una clase que típicamente se implementa como singleton es la de logging. Otros usos habituales son los diferentes managers de un programa (render, audio, etc...), aunque la utilidad y corrección real en esos casos es más discutible porque el código de render, audio, etc. no suele necesitar un acceso global, sino que se utiliza en una parte del código pequeña y específica. Si la visibilidad del objeto en cuestión no debe ser global, entonces olvídate de singletons, y céntrate en asegurar que sólo pueda crearse una instancia del mismo (lanzando una excepción, por ejemplo, en el caso de que esto no se cumpla).

Se suele considerar el singleton como un anti-patrón de diseño porque evita tener que pensar en la visibilidad de un objeto y realmente no es sino una manera más fina de tener globales en tu programa, con todo lo que ello conlleva.

Ruben

Cita de: "Pablo Zurita"

BTW, ninguna de esas implementaciones de singleton son thread-safe.

El operador new es "thread-safe", asi que teoricamente (y si lo dices por el new), la implementacion del singleton que usa new es "thread-safe". Aunque debes de liberar la memoria reservada a mano.

Y con la otra implementacion, evitas lo de liberar la memoria a mano pero entra en conflicto con las aplicaciones con multiples hilos.

Entonces, ¿porque dices que ninguna es "thread-safe"?

Flint

No son thread-safe. Por ejemplo, en la que ha puesto Lex, puede suceder:

- Un thread evalúa la expresión if (_instance == 0) y encuentra que es verdadera.
- Ahora viene otro thread, entra el if porque la expresión es verdadera y construye la instancia.
- Regresa el thread anterior al punto en el que quedó, y éste también construye una instancia.

Con lo que tenemos dos instancias y ¡pam!, nos hemos cargado el invento.

Pogacha

Para evitar esto se usa el doble chequeo:
theclass* getInstance() {
 if(!instance) {
   LOCK_THREAD
   if(!instance) instance = new theclass;
   UNLOCK_THREAD
 }
 return instance;
}


<HR>

Yengo este problema:

template<class T> class Singleton {
    Singleton()
    void operator=(const Singleton& );
  public:
    T* getInstance() {
          static T i;
          return &i;
   }
};

class Usandolo : public Singleton<Usandolo> {
 public:
   Usandolo();
   friend class Singleton<Usandolo>;
};


En modo debug me anda perfecto, pero en retail me crea multiples instancias ... VC 6.0 ... alguna solución?

Saludos

Pogacha

No soy el unico.

http://www.thescripts.com/forum/threadnav507963-1-10.html

No encontré solucion otra que desactivar optimizaciones, vere si puedo instalar el VisualExpress 2005

Si alguien sabe de algo se agradecera enormemente.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.