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

1

21.08.2012, 00:02

Spielerklasse als Singleton - Main gibt Spielerklasse zurück?

Hallo,

ich wollte innerhalb eines Textadventures die Spielerklasse als Singleton definieren. Jedoch habe ich jetzt die seltsamsten Fehler.
Hier die Singleton-Basisklasse:

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
42
43
44
45
46
#ifndef TSINGLETON
#define TSINGLETON

template <class T>
class TSingleton
{
    protected:

        static T *theInstance;   

        

        virtual ~TSingleton () {}

    public:

        // Memberfunktionen

        

        
        inline static T* Get ()
        {
            if (!theInstance)
                theInstance = new T; 

            return (theInstance);

        }

        static void Del ()
        {
            if (theInstance)
            {
                delete (theInstance); 
                theInstance = NULL; 
            }

        }

};

template <class T>
T* TSingleton<T>::theInstance = 0;

#endif


Das habe ich aus "C++ für Spieleprogrammierer" von Heiko Kalista übernommen, habe aber u.a. folgende Änderung vorgenommen: der Destruktor ist bei mir protected statt public.


Hier die Spielerklasse:

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
#include <iostream>
#include "TSingleton.hpp"
using namespace std;

#define thePlayer   CPlayer::Get()

class CPlayer : public TSingleton<CPlayer> {
    private:
        int m_PosX, m_PosY;
        int m_LifePoints;

        CPlayer ();
        ~CPlayer ();

    public: 
        int getLifePoints();
        void setValues();
        void outValues();
}


int CPlayer::getLifePoints () {
    return m_LifePoints;
}

void CPlayer::setValues() {
    m_LifePoints    = 100;
    m_PosX          = 0;
    m_PosY          = 0;
}

void CPlayer::outValues() {
    cout << "Lebenspunkte: "    << m_LifePoints << endl;
    cout << "Position: "        << m_PosX << ", " << m_PosY<< endl;
}


Und hier die main-Methode:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include "CPlayer.hpp"

int main() {
    thePlayer->setValues();
    //thePlayer->outValues();
    //CPlayer::Del();

    return 0;
}


Und die Fehlermeldung:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1>------ Erstellen gestartet: Projekt: TextAdventure, Konfiguration: Debug Win32 ------
1>  Main.cpp
1>MeinPfad\textadventure\main.cpp(4): error C2628: 'CPlayer' gefolgt von 'int' unzulässig (Semikolon ';' vergessen?)
1>MeinPfad\textadventure\main.cpp(4): error C3874: Der Rückgabetyp von "main" sollte "int" und nicht "CPlayer" sein
1>MeinPfad\textadventure\main.cpp(9): error C2664: 'CPlayer::CPlayer(const CPlayer &)': Konvertierung des Parameters 1 von 'int' in 'const CPlayer &' nicht möglich
1>          Ursache: Konvertierung von 'int' in 'const CPlayer' nicht möglich
1>          Quelltyp konnte von keinem Konstruktor angenommen werden, oder die Überladungsauflösung des Konstruktors ist mehrdeutig
1>  CPlayer.cpp
1>MeinPfad\textadventure\cplayer.cpp(12): error C2628: 'CPlayer' gefolgt von 'int' unzulässig (Semikolon ';' vergessen?)
1>MeinPfad\textadventure\cplayer.cpp(12): error C2556: 'CPlayer CPlayer::getLifePoints(void)': Überladene Funktion unterscheidet sich nur hinsichtlich des Rückgabetyps von 'int CPlayer::getLifePoints(void)'
1>          MeinPfad\textadventure\cplayer.hpp(23): Siehe Deklaration von 'CPlayer::getLifePoints'
1>MeinPfad\textadventure\cplayer.cpp(12): error C2371: 'CPlayer::getLifePoints': Neudefinition; unterschiedliche Basistypen
1>          MeinPfad\textadventure\cplayer.hpp(23): Siehe Deklaration von 'CPlayer::getLifePoints'
1>  Code wird generiert...
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========




Die ersten Fehlermeldungen versteh ich gar nicht... sieht aus, als sei "CPlayer" der Rückgabewert der main-Funktion, aber ich kann mir nicht erklären, wieso...

Kann mir jemand helfen?

PS: In der Suchfunktion hab ich nichts passendes gefunden.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

21.08.2012, 00:05

Willkommen im Forum.

Benutze niemals Singleton! :D

Unabhängig davon liegt der Fehler in Zeile 19 der CPlayer.hpp. Klassendefinitinoen müssen mit einem Semikolon abgeschlossen werden. Das steht auch so in der Fehlermeldung. Das nächste mal solltest du diese lesen und versuchen zu verstehen bevor du einen Thread eröffnest. :thumbsup:
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

3

21.08.2012, 07:53

Ein Singleton kann uU. schon recht sinnvoll sein. Also "Benutze niemals Singleton!" kann ich so nicht unterschreiben.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

21.08.2012, 08:06

Singleton hat genau einen einzigen Zweck: Zu verhindern, dass ein Objekt mehr als einmal instanziert werden kann, weil es nur genau einmal existieren darf. Der Begriff sollte mal übersetzt und analysiert werden, damit klar ist, worum es hier geht: Singleton - single. Es ist ein Einzelstück.
Mir ist daher kein einziger Fall in Hobby-Entwicklung bekannt, wo dies tatsächlich der Fall ist und alle mir bekannten Anwendungsformen sind lediglich eine andere (für Anfänger augenscheinlich professionelle und korrekte) Variante von globalen statischen Variablen. Singletons gehören in keinen Anfänger-Code, es ist das am meisten falsch verstandene und missbrauchte Pattern, das ich kenne.
Ein Player ist ganz sicher kein Singleton.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

5

21.08.2012, 11:26

Da hast du schon recht BlueCobold, in dem Beispiel ist ein Singleton unnötig.
Praktisch relevant wird es dann wenn es um Ausgaben in Dateien geht (Verhinderung von mehrfachen Zugriffen, Stichwort: synchronized) und klassisch bei Druckaufträgen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

21.08.2012, 11:51

In diesem Fall hier ist ein Singleton nicht nur unnötig, sondern sogar falsch. Für Druckaufträge und Dateiausgaben halte ich Locking und Semaphoren für die richtigen Werkzeuge, Singletons eher nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

21.08.2012, 13:05

Praktisch relevant wird es dann wenn es um Ausgaben in Dateien geht (Verhinderung von mehrfachen Zugriffen, Stichwort: synchronized) und klassisch bei Druckaufträgen.

Moment, kümmert sich nicht das Betriebssystem darum, dass nicht 2 Prozesse gleichzeitig in eine Datei schreiben? Unabhängig davon: Ein Singleton bedeutet nicht, dass nur einer in eine Datei schreiben kann, sondern dass es überhaupt nur ein (z.B. Logger-) Objekt geben kann, dass überhaupt in Dateien schreiben kann. Und es ist ja nicht so, dass man für jede Datei, die man schreiben will, eine eigene Klasse anlegt, sondern eben ein eigenes Objekt einer Klasse, die in Dateien schreiben kann. Und wenn die Datei dann eben schon geöffnet ist, schlägt die Objektkonstruktion fehl, oder es gibt sonst wo einen Fehler. Aber mit einer anderen Datei sollte man die Klasse immer noch benutzen können.
Es mag sein, dass es im Normalfall nicht sinnvoll ist, mehrere Logger-Objekte zu haben, es aber deshalb zu verbieten ist aber albern, weil es durchaus Situationen geben könnte, wo eben genau das sinnvoll ist.
Lieber dumm fragen, als dumm bleiben!

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

8

21.08.2012, 15:37

Ein Singleton kann uU. schon recht sinnvoll sein. Also "Benutze niemals Singleton!" kann ich so nicht unterschreiben.

Ich erkläre mal was ich mir dabei gedacht habe. :whistling:

Solang er Anfänger ist, bleibt meine Aussage gültig. Sobald er erfahren genug ist das Singletonpattern richtig zu nutzen, wird er meinen Tipp über Bord werfen und selbst entscheiden wann er es benutzt. Hätte ich ihm erklärt wofür das Singletonpattern da ist und ihm gesagt, dass er es noch nicht einschätzen kann, hätte er es vielleicht doch versucht und wäre auf die Nase gefallen. Eine absolute Aussage ist zwar selten richtig, aber meistens viel ausdrucksstärker.
Ausserdem musste ich nur drei Wörter schreiben. :thumbsup:
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

9

21.08.2012, 16:17

Könnten wir das ganze hier evtl. ausgliedern in einen "In welchem Fall sind Singletons sinnvoll" und dann wirklich auch Beispiele geben? Ist auf jeden Fall besser, als sich hier darüber zu streiten, was richtig und was falsch ist, danke :)
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

10

21.08.2012, 23:21

Erstmal danke für den Hinweis auf das fehlende Semikolon (gelöst ist die Sache dadurch aber noch nicht, ich werde evtl später den Fehlerbericht hochladen, da mein Internet zur Zeit spinnt und ich mit dem iPod schreiben muss).
Außerdem ist mir durchaus bewusst, dass die keine sinnvolle Anwendung von Singletons ist, ich wollte deren Prinzip praktisch erproben ;)

Werbeanzeige