Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

1

08.06.2006, 18:30

Singleton Klassen

Hallo, ich mal wieder ^^

Diesmal ein Problem mit Singleton Klassen, denke das sollte diesmal aber lösbar sein =)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class LUA
{
    //Methoden

    public :
        // Hier holen wir die Instanz der Klasse

        static  LUA * getInst();
        // Einen Textfile parsen

        void parseFile(std::string sLevelName);

    
    protected :
        LUA();
        virtual ~LUA(){};

    // Variablen

    protected:
        // Welche Datei behandeln wir gerade?

        wchar_t cFile[128];
        // LUA Singleton Instanz

        static LUA instLUA;
        // LUA Instanz innerhalb der Klasse

        lua_State* Lua_;
};
Eine Singleton Klasse eben =) Der Teufel steckt nun in der getInst() Methode. Diese sollte ja, wenn er zum ersten Mal aufgerufen wird, den Konstruktor aufrufen. Folglich sieht er so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
LUA* LUA::getInst()        
{
    if(instLUA == NULL)
    {
        instLUA = new instLUA();
    }
    
    return &instLUA;
}


Dummerweise haut mich mein Compiler dafür und sagt mir

C-/C++-Quelltext

1
2
3
4
mylua.cpp(39) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'LUA' (or there is no acceptable conversion)
        g:\proggingstuff\ms sdk\include\guiddef.h(192): could be 'int operator ==(const GUID &,const GUID &)'
        while trying to match the argument list '(LUA, int)'
g:\aurillion\techdemos\mapformat_gdi\src\mylua.cpp(41) : error C2061: syntax error : identifier 'instLUA'


Ich muss gestehen das ich weder groß Ahnung von Singletons noch von Lua habe :oops: Aber ich glaube fast das es an LUA liegt das diese Abfrage so nicht klappt, der Pointer scheint sich da irgendwie komisch zu verhalten ^^

Wie komme ich da am besten raus? Zur Not mach ich da einfach ne Abfrage per bool aber so richtig sauber erscheint mir das nicht ...

Anonymous

unregistriert

2

08.06.2006, 18:46

Diese Singletonklasse ist mir schon immer ein Dorn im Auge gewesen. Mit new wird immer Speicher reserviert aber nie frei gegeben. Dazu eine absolut grauenvolle Handhabung!

Benutz besser den Meyers-Singleton. Fehlerfrei, keine Probleme und einfach gut, vorallem da kein new benutzt wird und man eine Referenz bekommt und keinen Pointer.

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

3

08.06.2006, 19:04

Also, lies nochmal die Klassendefinition durch. Da steht:

C-/C++-Quelltext

1
static LUA instLUA;

Warum also nochmal mit new eine entsprechendes Objekt anfordern?

C-/C++-Quelltext

1
2
3
4
5
6
LUA LUA::instLUA; /* wichtig, weil instLUA ein static Member von LUA ist. */

LUA* LUA::getInst()
{
  return &instLUA;
}

reicht völlig.

Der Vergleich geht nicht, weil instLUA einfach gar kein Pointer ist. Der nächste Fehler wäre dann sofort bei der Zuweisung aufgetreten, weil man einem LUA Objekt auch keinen Zeiger auf ein LUA Objekt zuweisen kann.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

4

08.06.2006, 19:16

Oke, du darfst mich gleich für meine Aussage erschiessen aber:

Ist das in diesem Fall so grausam das der Speicher nicht wieder freigegeben wird? Die Singleton wird gleich zu Beginn hochgefahren und muss das ganze Programm hindurch laufen, sonst gibts massig Probleme. Und wenn ich das Programm dann schliesse wird der Speicher ja eh wieder freigegeben?

Mir ist schon klar das guter Code etwas vollkommen anderes ist, aber erstmal geht es mir darum mein Problem zu lösen xD

Meyers Singleton? Trotzdem mal einen Blick drauf werfen, glaube aber nicht das mein Problem dadurch gelöst wird xD

Edit:
rklaffehn
Dann muss ich den Konstruktor aber nochmal manuell aufrufen oder nicht? Also doch mit ner bool Abfrage ...

Lemming

Alter Hase

Beiträge: 550

Beruf: Schüler

  • Private Nachricht senden

5

08.06.2006, 19:22

Re: Singleton Klassen

Zitat von »"Das Gurke"«

C-/C++-Quelltext

1
2
        // LUA Singleton Instanz

        static LUA instLUA;

wie rklaffehn schon gesagt hat ist das problem, dass dein instanz pointer gar kein pointer ist! du hast den '*' vergessen.
daher auch die compiler meldung, dass er ein objekt vom typ LUA nicht mit einem wert wie NULL vergleichen kann.
also entweder setzt du einen * daziwischen, damit das auch wirklich ein pointer wird. oder du machst nen meyer singleton.
Es gibt Probleme, die kann man nicht lösen.
Für alles andere gibt es C++...

Anonymous

unregistriert

6

08.06.2006, 19:41

Das Gurke
Benutz nen anständigen Singleton und nicht diesen Murks da!

C-/C++-Quelltext

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
class debug
{
private:
        // Constructor, Copyconstructor und Destructor

    debug  (void);
    debug  (const debug& other);
    ~debug (void);

        // Es gibt nur eine Instanz. Jede Zuweisung wäre eine Selbstzuweisung.

        // Da Selbstzuweisungen selten Sinn machen, ist der op= privat

    debug& operator= (const debug& other);

public:
        // Diese statische Methode erzeugt die einzige Instanz.

        // Nur über diese Methode erhalten Anwender den Zugriff auf

        // die Instanz.

    inline static debug& getInstance (void)
    {
            // Die Instanz wird erst beim ersten Aufruf erzeugt.

            // Endet das Programm, wird Instanz vernichtet.

        static debug instance;
        return (instance);
    } 

        // Freundschaften

    friend class debug_stack_buffer;    // Der Debugstackbuffer hat vollen Zugriff

    friend class exception;             // Exception hat vollen Zugriff

    friend class hardwareexception;     // Hardwareexception hat vollen Zugriff


private:
        // Funktionen zum Pushen und Poppen eines Funktionsnamens

    void push   (const std::basic_string<wchar_t>& function);
    void pop    (const std::basic_string<wchar_t>& function);

        // Getter für Informationen

    const std::basic_string<wchar_t> getPath     (void);
    const std::basic_string<wchar_t> getFunction (void);

        // Stack für die Funktionsnamen

    ttl::stack<std::basic_string<wchar_t> > stack_;
};

ext

Treue Seele

  • Private Nachricht senden

7

08.06.2006, 21:12

Das Gurke, du hast recht, wenn du ein Singleton brauchst, das bis zum bitteren Ende da ist, dann musst du das so machen und das Speicherleck in kauf nehmen.
In dem Buch "Modern C++ Design" stellt Andrei Alexandrescu verschiedene Singletons vor, darunter auch deins.
Ne ähnliche alternative ist das Phoenix-Singleton, das sich am Programmende (mit exit-handler) sich selbst löscht, aber jeder zeit wieder erschaffen kann, wenn nochmals darauf zugegriffen wird (dann wird wieder ein exit-handler gesetzt).
Kannst ja mal in seine Loki-Bibliothek reinschauen und dir die verschiedenen Singleton-Arten anschauen, vielleicht gibts ja eine Variante die besser für dich passt.

Das Gurke

Community-Fossil

  • »Das Gurke« ist der Autor dieses Themas

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

8

08.06.2006, 21:55

Gut, immerhin schein ich ja nicht völlig danebenzuliegen mit meiner Methode =)

Wollte nur nochmal allen hier für ihre Hilfe danken, das Problem ist mittlerweile aus der Welt, der Teufel steckte im fehlenden *

C-/C++-Quelltext

1
static LUA instLUA;
Irgendwie peinlich :roll: Obwohl es eigtl noch peinlicher ist das mich gleich 2 Leute drauf hinweisen mussten *hust* Aber hier darf man das ja =)

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

9

09.06.2006, 06:56

Schau nochmal, was ich dazu geschrieben habe...

Du muss das nicht als Zeiger behandeln, aber wenn die direkt LUA als static Member hast, musst du das (ausserhalb einer Methode) initialisieren. Dabei wird dann auch der Konstruktor aufgerufen. (bei mir die einzige Zeile mit Kommentar dahinter)

Aber, so wie nix da das schreibt, ist das noch ein wenig schicker, weil man da die statische Initialisierung der Membervariable nicht vergessen kann -- also als static Variable innerhalb der getInst Methode.

Eine bool Variable brauchst du dafür in beiden Fällen nicht, weil static Variable garantiert nur einmal initialisiert werden.

Ein Speicherleck ist die Implementation mit Zeigern erst, wenn ich gar keine Möglichkeit mehr habe, den Speicher mehr freizugeben, was in diesem Fall nicht so ist. Der Punkt ist eben, dass man selbst sicherstellen muss, dass der Speicher am Ende wieder freigegeben wird, was man bei der Variante mit static Variablen nicht braucht.

Ich würde trotzdem die Variante von nix da empfehlen.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

10

09.06.2006, 09:43

Ich finde ein Vorteil von Gurkes Variante ist noch die Möglichkeit, den Speicher vor Programmende freizugeben. Ist aber zugegebener Maßen auch der einzige^^

Werbeanzeige