Problem Singelton

Hi Leute!

Folgendes Problem mit meinem Singelton im C++ Proggi:

Ich habe eine Klasse Kundenverwaltung:

Code:
class Kundenverwaltung
{

private:
list Konten;
list::iterator kontoit;

list Kunden;
list::iterator kundeit;

static Kundenverwaltung* kverw;

protected:
Kundenverwaltung();

public:

static Kundenverwaltung* getKundenverwaltung()
{
if(kverw==NULL)
{
kverw= new Kundenverwaltung();
}
return kverw;
}
}

Obiger Code sollte einen lauffähigen Singelton repräsentieren.
Zugriff auf die Klasseninstanz von anderer Klasse aus mittels:

Code:
(Kundenverwaltung::getKundenverwaltung())->validateKonto(KontoNr, Pin)

Leider folgendes Problem in der Entwicklungsumgebung Visual Studio .NET:
ERROR der Ausgegeben wird:

error LNK2020: Nicht aufgelöstes Token (0A00001F) ?kverw@Kundenverwaltung@@0PAV1@A

fatal error LNK1120: 1 unaufgelöste externe Verweise

Vielleicht hat jemand eine Ahnung, was hier falsch gemacht wird!
Danke im Voraus!
LG, Klaus

Hallo

Was mir spontan auffält ist, dass der Konstruktor nicht implementiert ist und dass das „;“ am Ende der Klassendeklaration fehlt.

class Kundenverwaltung
{
 // ...
 protected:
 Kundenverwaltung() { // Hier darf was rein }
 ~Kundenverwaltung(){ // Das darf auch sein }
 // ...
}; // Hier ein ";"

Gruss, Olli

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

… im Konstruktor könntest du zum Beispiel den Zeiger auf Kundenverwaltung mit NULL initialisieren. Ich arbeite mit g++ und der macht das nicht automatisch. Dadurch würde die Klasse nie angelegt werden , wegen if(kverw==NULL). Also:

class Kundenverwaltung
{
 // ...
 protected:
 Kundenverwaltung() { Kundenverwaltung::kverw = NULL; }
 ~Kundenverwaltung(){ delete Kundenverwaltung::kverw; }
 // ...
};

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

… im Konstruktor könntest du zum Beispiel den Zeiger auf
Kundenverwaltung mit NULL initialisieren. Ich arbeite mit g++
und der macht das nicht automatisch. Dadurch würde die Klasse
nie angelegt werden , wegen if(kverw==NULL). Also:

class Kundenverwaltung
{
// …
protected:
Kundenverwaltung() { Kundenverwaltung::kverw = NULL; }
~Kundenverwaltung(){ delete Kundenverwaltung::kverw; }
// …
};

sollte man statische Elemente nicht auch statisch initialisieren ?
also ich kenn und mach das dann in der zugehörigen *.cpp-Datei immer mit
z.B.

Kundenverwaltung * Kundenverwaltung::kverw = 0;

dann ist die initialisierung im Konstruktor nicht mißverständlich, da nach meinem Verständnis dieser kein Wissen darüber haben muss, ob das objekt schon angelegt wurde.

und im desktruktor darf doch auf keinen fall noch einmal der destruktor aufgerufen werden -> das würde doch eine entlosschleife werden ?!

ich hab mir für Singletons folgendes Template angelegt:

template
class TSingleton
{
public:
 static C \*instance ()
 {
 if (!instance\_)
 instance\_ = new C ();
 return instance\_;
 }

 virtual
 ~TSingleton ()
 {
 instance\_ = NULL;
 }
protected:
 TSingleton () { };
private:
 static C \*instance\_;
};

template C\* TSingleton ::instance\_ = NULL;

ein singleton kann man dann einfach ableiten:

class CApplication : public TSingleton 
{
friend class TSingleton ;
public:
 ~CApplication () {};
 static CApplication \* instance ()
 {
 return TSingleton ::instance ();
 }
protected:
 CApplication () {};
};

mfg TLF

Hallo,

… im Konstruktor könntest du zum Beispiel den Zeiger auf
Kundenverwaltung mit NULL initialisieren. Ich arbeite mit g++
und der macht das nicht automatisch. Dadurch würde die Klasse
nie angelegt werden , wegen if(kverw==NULL). Also:

class Kundenverwaltung
{
// …
protected:
Kundenverwaltung() { Kundenverwaltung::kverw = NULL; }
~Kundenverwaltung(){ delete Kundenverwaltung::kverw; }
// …
};

Ähem. Also das is auch ne seltsame lösung, normalerweise siehts so aus:

class Singleton
{
 Singleton() {}
 ~Singleton() {}

 void killMe() { delete mInstance; }

public:
 Singleton\* getInstance()
 {
 if ( mInstance == NULL )
 {
 mInstance = new Singleton;
 atexit(Singleton::killMe);
 }
 return mInstance;
 }

private:
 Singleton\* mInstance;
}

Singleton\* Singleton::mInstance = NULL;

Auch Visual C++ setzt Pointer Variablen nicht selbst auf NULL :wink:

mfg,
Christoph

Ups,

mInstance is natürlich static :stuck_out_tongue:

Stimmt, statische Attribute müssen natürlich auch statisch initialisert werden, genau so wie du das vorschlägts. Danke für die Korrektur, war ein Denkfehler meinerseits. Danke ck

Aber dass das statische Attribut mit NULL initialisert weden muss, da sind wir uns einig.

Grüsse, Olli

Ups,

mInstance is natürlich static :stuck_out_tongue:

Öhm, ich möchte ja hier nicht klugscheissern, aber… tu ich ja doch. *g*

Sollten nicht Copy-Konstruktor und Zuweisungsoperator auch private sein? Sonst lassen sich ja bumsti zwei Singletons im Prozessraum generieren…

kvida

Hallo,

Kann gut sein, aber ich glaub das ist nicht nötig:

Singleton\* p = Singleton::getInstance(); // Gültig
Singleton\* pkopie = p; // Auch Gültig, weil ja nurn Zeiger aufs andere
Singleton kopie(\*p); // Ungültig, weil geht auf den Konstruktor(private)
Singleton\* kopie2;
\*kopie2 = \*p; // Vielleicht gültig, aber benutzen führt zum crash?

So denk ich isses zumindest, ausprobieren war mir jetzt zuviel Arbeit :wink:

bye,
Christoph

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]