Dev - C++ - ¿Cuál es la forma correcta?

 
Vista:

¿Cuál es la forma correcta?

Publicado por Agustin (2 intervenciones) el 01/08/2015 05:50:30
Hola, qué tal, estoy con un dilema del cual no he podido encontrar nada ni quitarme la duda por Internet.

¿Cuál es la forma correcta? yo tengo una Class y aplico Singleton para poder utilizar las variables junto con sus métodos en todo el programa.

Ahora mi duda es la siguiente, yo para llamar a los métodos o a las variables de la clase común hago ésto:

Class object;
object.method(...) or variable;

En singleton:
object.getInstance()->method(...) or variable;

Y también en algunos casos, para no generar en otro objecto del tipo Class, en otro "archivo.cpp" hice lo siguiente:

Class::getInstance()->method(...) or variable;

El depurador me lo marca como que está mal hacer éso, pero sin embargo me compila todo bien, luego si yo creo el objeto en cada "archivo.cpp" y trabajo de esa manera medio rara en mi parecer, el Depurador me muestra todo okey, pero me tira que el ejecutable dejó de funcionar, etc. y se cierra todo.

Además, si hago Class:getInstance()->method(...) or variable; || cuando manejo las variables, se generan errores raros en la memoria.

Sin entrar en más detalles, quisiera que algún experto pudiese ayudarme y explicarme cuál es la forma correcta de usar Singleton en diferentes archivos, contextos, o como sea.

Desde ya, gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de vangodp
Val: 73
Ha disminuido 1 puesto en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

¿Cuál es la forma correcta?

Publicado por vangodp (287 intervenciones) el 01/08/2015 12:08:09
No debería haber ningún problema ya que getinstance siempre debería devolver el puntero a la misma instancia o de no haber una se la debería crear. Deberías checkar la función getInstance si esta correctamente implementada, creo que el problema esta ahí.

Prepare una clase algo similar a la que comentas, para que pruebes, no sé exactamente como esta la tuya, pero según lo que comentas la idea es la misma. Ella avisa cuando intentas acceder a una instancia que ya existe, o cuando haya creado una por primera vez.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
using namespace std;
 
class Class {
public:
    static Class* getInstance();
    void setInt(int unEntero) { suEntero = unEntero; cout << "suEntero establecido a " << suEntero << endl; }
    void getInt() const { cout << "El entero es = " << suEntero << endl; }
protected:
    Class();
    Class ( const Class & );
    Class &operator= ( const Class & );
private:
    static Class* laInstancia;
    int suEntero;
};
 
Class* Class::laInstancia = 0;// Inicializar el puntero
 
Class* Class::getInstance () {
    if ( laInstancia == 0 ) { // ¿Es la primera llamada?
        cout << "Instacia creada" << endl;
        laInstancia = new Class; // Creamos la instancia
    }else{
        cout << "Ya existe una instancia! Se retorna el puntero a esa instancia" << endl;
    }
    return laInstancia; // Retornamos la dirección de la instancia
}
 
Class::Class() :suEntero(0)  {
    //... Realizar inicializaciones necesarias de la instancia
}
 
 
int main () {
    cout << "Creando primera instancia"<< endl;
    Class *p1 = Class::getInstance();
 
    cout << "Copiando instancia"<< endl;
    Class *p2 = p1->getInstance();
 
    cout << "Obteniendo una referencia de la instancia" << endl;
    Class &ref = * Class::getInstance();
 
    //Si no existiera una instancia en los casos anteriores siempre
    Class::getInstance()->setInt(100);
    Class::getInstance()->getInt();
 
    cin.ignore();
    return 0;
}

Pruebala y si te queda dudas comente =)

Te dejo 2 articulos para que leas:
1
http://plagatux.es/2008/09/c-patron-de-diseno-singleton/
1
https://caymcorp.wordpress.com/2010/09/28/singletons-en-c-el-problema-de-la-destruccion/

No abuses mucho de ese patrón. Úsalo cuando sea realmente necesario. ;)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

¿Cuál es la forma correcta?

Publicado por Agustin (2 intervenciones) el 01/08/2015 17:40:12
Mira, yo lo hago de la siguiente manera:

class cMain
{
protected:
static cMain* pI;

public:
~cMain(){delete cMain::pI;}
static void setInterface(cMain* newInterface){pI = newInterface;}
static cMain* p_cGIn(){return pI;}
}
//supongamos que cMain proviene de otro "archivo.cpp"

cMain Main;

int main()
{
Main.setInterface(&Main);
//o también en otros casos en vez de crear el Objeto, lo hago de la siguiente manera:
cMain::setInterface(new cMain());
}

¿Éso estaría bien?, porque me tira que no responde el programa y por lo que me estuve fijando, me lo produce éso.

PD: Gracias por tu mensaje, lo de la eliminación del Singleton me imaginaba que era necesario y lo hacía bien, sólo que no sabía en qué ocasiones debería utilizarlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de vangodp
Val: 73
Ha disminuido 1 puesto en Dev - C++ (en relación al último mes)
Gráfica de Dev - C++

¿Cuál es la forma correcta?

Publicado por vangodp (287 intervenciones) el 01/08/2015 19:37:27
¿¿Seguro que eso es un patrón singleton?? Si llegara a funcionar... En todo caso no le veo el uso.

cuando la creas cMain Main; se instancia en la pila, ya no hay lógica guardar un puntero dentro de ella mismo ya que para eso esta el puntero this (Main.setInterface ( &Main );). =/

Realmente no comprendo nada en absoluto ese su código... ¿De donde lo has sacado por curiosidad?

El patrón singletón debe garantizar que solo haya una instancia en la memoria de dicha clase, en ninguna parte veo esa comprobación. llames de donde la llames, siempre te va devolver un puntero a esa instancia. Pero en fin, siento no poder ayudar porque realmente no entiendo el concepto de esa idea.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar