• Domingo 22 de Diciembre de 2024, 22:22

Autor Tema:  Constructor Privado  (Leído 1882 veces)

nicokiki

  • Miembro MUY activo
  • ***
  • Mensajes: 298
    • Ver Perfil
Constructor Privado
« en: Viernes 27 de Febrero de 2004, 16:00 »
0
Hola a todos!!

Les planteo la siguiente duda. Si yo quisiera instanciar solo una "instancia" de una clase, tendria que implementar un constructor privado. El problema q tengo es q no se muy bien como hacerlo.

Si alguien me da una mano....

Salu2!!!!!!

CiRRuS

  • Miembro MUY activo
  • ***
  • Mensajes: 218
    • Ver Perfil
    • http://zirrus.es
Re: Constructor Privado
« Respuesta #1 en: Viernes 27 de Febrero de 2004, 21:03 »
0
Eso yo lo tuve que hacer para Java, a ver si lo adapto para C:

Debes declarar al contructor como privador y luego crear un método estático de la clase que al llamarlo cree la instancia de la clase, y si ya esta creada devuelva a ella misma.

Código: Text
  1.  
  2. class A {
  3.   private:
  4.     A instancia=null;
  5.     A();
  6.   public:
  7.     static A getInstancia();
  8. };
  9.  
  10. A A::getInstancia() {
  11.     if(instancia == null) return new A();
  12.     else return instancia;
  13. }
  14.  
  15.  

Espero haber realizado un código correcto... pero sobre todo que se vea clara la idea

¿Era eso lo que buscabas? ¿respondo a tu pregunta?

Nos vemos :hola:
Core Dumped
zirrus.es

nicokiki

  • Miembro MUY activo
  • ***
  • Mensajes: 298
    • Ver Perfil
Re: Constructor Privado
« Respuesta #2 en: Viernes 27 de Febrero de 2004, 21:37 »
0
Gracias!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Eso era lo q necesitaba

Salu2!!!!!!

P.D.: Apoyen la solicitud de apertura del foro de JSP/Servlets!!!!!!!!!

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Constructor Privado
« Respuesta #3 en: Sábado 28 de Febrero de 2004, 13:12 »
0
Citar
Código: Text
  1.  
  2. class A {
  3.  private:
  4.    A instancia=null;
  5.    A();
  6.  public:
  7.    static A getInstancia();
  8. };
  9.  
  10. A A::getInstancia() {
  11.    if(instancia == null) return new A();
  12.    else return instancia;
  13. }
  14.  
  15.  

Francamente, me gustaría saber si alguno de vosotros ha compilado ese fragmento de código, porque según veo ha de dar errores de todo tipo por todas partes. Además, si consiguieras hacer eso funcionar generarías una nueva instancia en cada llamada a getInstancia().

Una forma correcta de hacer eso (que se llama singleton) y bastante probada es hacer esto:

Código: Text
  1.  
  2. // En el fichero .h
  3. class A
  4. {
  5. public:
  6.     // Métodos que hagan falta
  7.     // ...
  8.  
  9.     ~A() { /* código destructor */}
  10.  
  11.     // Retorna la única instancia de la clase
  12.     static A *Instancia() {return &m_A;};
  13.  
  14. private:
  15.     static A m_A;
  16.  
  17.     A() { /* código constructor */ };
  18.  
  19.     // El constructor de copias tambien debe
  20.     // ser privado
  21.     A(const A &);
  22.  
  23.     // Otros miembros privados
  24.     // ...
  25. };
  26.  
  27. // En el fichero .cpp
  28.  
  29. // Para dar presencia física a la variable
  30. // estática
  31. A A::m_a;
  32.  
  33. // Implementar aqui el resto de métodos de la clase
  34.  
  35.  
  36.  

De esta forma, para acceder a la instancia se podría hacer esto en el código:

Código: Text
  1.  
  2. A::Instancia()->método1();
  3.  
  4. o también
  5.  
  6. A *pA = A::Instancia();
  7. pA->método1();
  8. pA->método2();
  9.  
  10.  

Hay que tener en cuenta que no hay que liberar los punteros, ya que apuntan a m_A, que será automáticamente liberado cuando sea llamado el destructor de la clase.

Esto tiene el problema del orden de inicialización si se llaman entre sí varias clases de este tipo en los constructores, pero se puede arreglar moviendo m_A al interior de Instancia() en forma de variable estática, por lo que será inicializado en la primera llamada a Instancia().

Creo que no he cometido ningún error en el código. Si no es así que alguien me lo diga.

Espero que esto te haya servido de ayuda.

Un saludo.

Ruben3D

CiRRuS

  • Miembro MUY activo
  • ***
  • Mensajes: 218
    • Ver Perfil
    • http://zirrus.es
Re: Constructor Privado
« Respuesta #4 en: Sábado 28 de Febrero de 2004, 13:22 »
0
Citar
Francamente, me gustaría saber si alguno de vosotros ha compilado ese fragmento de código, porque según veo ha de dar errores de todo tipo por todas partes. Además, si consiguieras hacer eso funcionar generarías una nueva instancia en cada llamada a getInstancia().

Sorry  :( , ya dije q no se si estaría libre de errores y q me basaba en una "idea" que tuve en Java...

No pretendia hacer código perfecto (más que nada porque no tenía mucho tiempo para terminar mi post...), solamente mostrar la idea... Aunque ese if ya veo que ta rotundamente mal, no tuve tiempo para verificar la correcion.

Me apunto tu singleton.

Nos vemos :hola:
Core Dumped
zirrus.es

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Constructor Privado
« Respuesta #5 en: Sábado 28 de Febrero de 2004, 13:33 »
0
Citar
Sorry  , ya dije q no se si estaría libre de errores y q me basaba en una "idea" que tuve en Java...

 :o  Siento haber parecido un poco brusco. No lo pretendía.

Un saludo.

Ruben3d

QliX=D!

  • Miembro MUY activo
  • ***
  • Mensajes: 214
    • Ver Perfil
Re: Constructor Privado
« Respuesta #6 en: Jueves 4 de Marzo de 2004, 14:47 »
0
Bueno si eso es un patron, se llama Singleton y podras encontrar mas info al respecto en:

http://www.geocities.com/cordayuk/Direct3D...anda/diseno.htm

Y la guia completita de patrones (hay mas pero estos son lo de Gamma et al.)

http://webs.teleprogramadores.com/patrones/

Tambien esta el Singleton :D

Slds.-
QliX=D! - From the top of Tsunami

ToTeX

  • Nuevo Miembro
  • *
  • Mensajes: 19
    • Ver Perfil
    • http://www.totex.cl
Re: Constructor Privado
« Respuesta #7 en: Jueves 4 de Marzo de 2004, 17:43 »
0
Hola, yo uso siempre singletons en mis juegos y en otros programas donde necesito instancias unicas. He visto hartos ejemplos en internet pero ninguno me dejo satisfecho, asi que me hice una propia. La ventaja de la implementacion que les presento es que uno solo deriva cualquier clase de CSinlgeton y punto. Solo hay que tener presente que hay que llamar al destructor al fin del programa, pues la instancia unica se crea mediante un new, por lo tanto no se llama al destructor automaticamente. Otro punto es que el programa al partir crea todos los singletons, por lo tanto no se pueden hacer constructores con parametros, por eso generalemente yo creo un metodo, en la clase derivada, que haga la construccion, asi controlo en el main yo mismo el orden en que se crean los singletons y le puedo pasar parametros.

singleton.h
Código: Text
  1.  
  2. #if !defined(SINGLETON_DEC)
  3. #define SINGLETON_DEC
  4.  
  5.  
  6. //Clase CSingleton, base para derivar singletons
  7.  
  8. template<class CLASS> class CSingleton
  9. {
  10.   protected:
  11.     static CSingleton<CLASS>* m_poObj;
  12.   public:
  13.     CLASS* poObj()
  14.     {
  15.       if(!m_poObj)
  16.         m_poObj=new CLASS();
  17.       return (CLASS*)m_poObj;
  18.     }
  19. };
  20. template<class CLASS> CSingleton<CLASS>* CSingleton<CLASS>::m_poObj=new CLASS();
  21.  
  22.  
  23. /*
  24.   Esta funcion ahorra lineas de codigo, sirve para inicializar un puntero
  25.   a alguna Clase derivada de CSingleton.
  26. */
  27. template<class CLASS> CLASS* poSingleton()
  28. {
  29.   CLASS* poSingleObject=(CLASS*)0;
  30.   poSingleObject=poSingleObject->poObj();
  31.   return poSingleObject;
  32. }
  33.  
  34. #endif
  35.  
  36.  
  37.  


main.cpp
Código: Text
  1.  
  2. #include <iostream>
  3. #include "singleton.h"
  4.  
  5. using namespace std;
  6.  
  7. class A:public CSingleton<A>
  8. {
  9.   public:
  10.     A(){cout<<"construyendo A"<<endl;}
  11.     ~A(){cout<<"destruyendo A"<<endl;}
  12. };
  13.  
  14. class C
  15. {
  16.   public:
  17.     C(){cout<<"construyendo C"<<endl;}
  18.     ~C(){cout<<"destruyendo C"<<endl;}
  19. };
  20.  
  21. class B:public CSingleton<B>,public C
  22. {
  23.   public:
  24.     B(){cout<<"construyendo B"<<endl;}
  25.     ~B(){cout<<"destruyendo B"<<endl;}
  26. };
  27.  
  28. int main()
  29. {
  30.   A *p1=poSingleton<A>();
  31.   B *p2=poSingleton<B>();
  32.   delete p1;
  33.   delete p2;
  34.   return 0;
  35. }
  36.  


Una alternativa interesante y a veces mejor(en mi opinion) son los namespaces. Son bastante comodos, ademas de que sus variables y metodos son "unicos", El unico problema es que se viola la encapsulacion, ademas de la imposibilidad de usar alguna clase base como se haria al construir un singleton derivado.
Salu2... ToTeX
[ www.totex.cl ]