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

17.01.2012, 07:25

Singleton - Unbehandelte Ausnahme bei...

Hallo!

Bin neu hier, freue mich jetzt auch endlich mal ein Spiel entwickeln zu dürfen :)

Habe leider schon gleich ein Problem. Man kann sagen irgendwas stimmt einfach nicht mit der Singleton Class.
Was ich vorhabe ist, in einer Klasse A Funktionen und Variablen einer Klasse B zu benutzen (Vererbung geht nicht.. weil es später viel komplexer wird).
Deshalb dachte ich, warum erstelle ich nicht einfach Klasse B als Singleton (Klasse A zwar auch aber das ist in diesem Beispiel eigentlich egal).

An genau der Stelle wo ich in Klasse A eine Funktion von Klasse B aufrufe gibt er mir ne "Unbehandelte Ausnahme" und dass ich angeblich den Heap verletzt habe.

Singleton:

Quellcode

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
#ifndef TSINGLETON
#define TSINGLETON

template <class T>
class TSingleton
{
protected:
    static T* pSingleton;

public:
    virtual ~TSingleton()
    {
    }

    inline static T* GetInstance()
    {
        if (!pSingleton)
        {
            pSingleton = new T;
            return pSingleton;
        }
    }

    static void ReleaseInstance()
    {
        if (pSingleton)
        {
            delete (pSingleton);
            pSingleton = NULL;
        }
    }
};

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

#endif


Klasse A:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#ifndef FRAMEWORK
#define FRAMEWORK

#include "Singleton.h"
#include "Surface.h" // Klasse B

#define Framework cFramework::GetInstance()

class cFramework : public TSingleton<cFramework>
{
public:
    void Run();
};

#endif

void cFramework::Run()
{
    SDL_Surface* Test = NULL;
    Test = Surface->LoadSurface("..\\test.png"); // <--- Hier die Funktion von Klasse B
}


Klasse B ist genau geschrieben wie Klasse A... auch mit Singleton usw.
Woran kann das liegen? Er scheint einfach nicht Funktionen von B in A auszuführen und umgekehrt.
Wäre über jede Hilfe dankbar.

Danke schonmal
MfG Clark

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

17.01.2012, 07:33

Das wird Dir jetzt nicht gefallen, aber: Mach weder A, noch B zum Singleton. Ein Singleton sollte nur verwendet werden, wenn es unter gar keinen Umständen mehr als eine einzelne Instanz einer Klasse geben darf. Bei Dir scheint mir das nicht plausibel und eher so, als würdest Du es verwenden wollen, weil Du weißt, dass es das gibt. Finger weg davon. Du brauchst es nicht, arbeite ohne. Härter ausgedrückt solltest Du es auf keinen Fall verwenden, egal was im Buch steht, eigne Dir das gleich als eiserne Regel an und Du sparst Dir viel Ärger und Probleme, weil Du Singleton falsch verwendet hast. Sie sind schlechter Stil (werden verwendet wie globale Variablen, die ebenfalls sehr schlechter Stil sind) und Hinweis auf schlechtes Code-Verständnis.
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]

3

17.01.2012, 07:36

Ok das dachte ich eigentlich auch. Und doch.. das hilft mir weiter haha :D nicht dass ich schon länger eine Abneigung gegen Singleton oder so habe... egal.

Nehmen wir mal an ich hab 5 Klassen und die müssen alle gegenseitig aufeinander zugreifen in Punkto Variablen und Funktionen .. wie realisiere ich das denn?
Mit Friend Klassen? Kann das sein? So entwickelt man Spiele?

EDIT: Ok mit Friends geht es schonmal nicht...

EDIT2: Simpler gefragt.. nehmen wir mal an ich habe Game.Run() (Klasse) laufen.. wo halt die Eventschleife ist und das Spiel stattfindet. Jetzt will ich dort drin z.B. den Timer ansprechen (der auch eine Klasse ist).
Wie geht das?

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Clark« (17.01.2012, 08:18)


Powerpaule

Treue Seele

Beiträge: 162

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

4

17.01.2012, 08:35

EDIT2: Simpler gefragt.. nehmen wir mal an ich habe Game.Run() (Klasse) laufen.. wo halt die Eventschleife ist und das Spiel stattfindet. Jetzt will ich dort drin z.B. den Timer ansprechen (der auch eine Klasse ist).
Wie geht das?
Na dann hast du in der Klasse "Game" eine Membervariable(Ich hoffe du weißt was das ist?^^) vom Typ "Timer". Das Timer-Objekt kannst du ja im Konstruktor der Game-Klasse erzeugen. Also du hast ja die Klassen in der Regel dafür, um Objekte von deren Typ zu erstellen - Man benutzt ja nicht die Klasse selber, sondern ein Objekt davon, außer du machst alles static aber dann ist hast du quasi den gleichen Designfehler wie mit Singletons, und könntest dann auch nicht mehr als bspw. 1 Timer haben...

Nehmen wir mal an ich hab 5 Klassen und die müssen alle gegenseitig aufeinander zugreifen in Punkto Variablen und Funktionen .. wie realisiere ich das denn?
Am besten gar nicht, das klingt dann sehr nach Spagetti-Code ; ) Überleg dir lieber genau was für Klassen du brauchst, und wie diese voneinander abhängig sind. Wenn du dir da zu deinem Entwurf eine Meinung holen willst, kannst du das natülrich hier gerne machen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Powerpaule« (17.01.2012, 08:40)


5

17.01.2012, 08:40

Danke für die Antwort. Hmm am liebsten würde ich die ganzen Klassen irgendwie "global" machen, so dass ich überall darauf zugreifen kann. Eine lokale Membervariable vom Typ Timer macht eigentlich keinen Sinn denn:

Mal folgendes angenommen: Game, Timer und Player sind Klassen. In Game muss ich den Timer aktualisieren und in Player wird der Timer auch benutzt und eventuell noch Player in Game.
Ich bin leider verwirrt weiß nicht wie ich das hinbekomme.

EDIT: Ich meine es ist eigentlich klar, dass ich überall in fast jeder Klasse in einem Game auf die Timerklasse zugreifen können muss und diese darf natürlich nicht jedesmal neu erstellt werden sonst würde der Timer ja keinen Sinn ergeben. Hmm wenn es wirklich am Design liegt, wie löst man dann so ein Problem?

EDIT2: Oder noch simpler: Das Logfile. Ich muss ja überall auf das Logfile zugreifen können wenn ich nur eins haben will... in allen Klassen eben.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Clark« (17.01.2012, 08:50)


Powerpaule

Treue Seele

Beiträge: 162

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

6

17.01.2012, 10:05

Also deine Überlegungen sind schon nicht so falsch, nur die Schlüsse die du daraus ziehst, passen nicht so recht. Im Grunde willst du, dass alle (bisher 2) Klassen denselben Timer verwenden - und daraus schlussfolgerst du jetzt, die Klasse Timer als Singleton zu machen. Das ist aber nicht logisch, denn was wenn du später einen weiteren Timer brauchst? Dann klappt es nicht. Und genauer gesagt - was spricht dafür, dass ein Timer nur einmal existieren sollte? Ein Singleton macht wirklich nur selten Sinn. (Bei einem Ressourcen-Manager hätte man vielleicht einen sinnvollen Einsatz) Das mit der Logfile-Klasse, da hast das schon besser getroffen, hier ist es durchaus keine schlechte Idee, die Klasse als Singleton zu machen, das kannst du also so machen (wobei man sich da natürlich auch streiten kann, ob man nicht vllt. mehrere Logfiles haben will etc).

Also, du hast ja jetzt schon die Abhängigkeiten deiner Klassen erläutert: Game benutzt Player, und Game und Player benutzen denselben Timer. Was also spricht dagegen, wenn du den Timer in der Game-Klasse erzeugst, danach das oder die Player-Objekte erzeugst (in Game), und diesen Objekten eine Referenz auf das bereits erzeugte Timer-Objekt übergibst? Dann bräuchtest du auf jeden fall den Timer nicht global.

Als nächstes könnte man natürlich noch fragen, wieso die Klasse Player den Timer überhaupt braucht, und nicht einfach die Klasse Game in jedem Schleifendurchlauf bei allen Player-Objekten sowas wie update() aufruft (und dort eventuell noch die vergangene Zeit oder sowas mit übergibt) - dann hättest du in der Player-Klasse ein Problem weniger und eine zentrale Stelle, an der die Zeit-Sachen berechnet werden,

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

17.01.2012, 10:21

Jup, Powerpaule hat vollkommen Recht. Geteilte benutzte Ressourcen an einer Stelle verwalten und den Instanzen übergeben, die diese brauchen: Das Game erstellt eine Timer-Instanz und den übergibt es (am besten gleich im Konstruktor) an die ebenfalls von ihm erzeugten Player-Instanzen. Auf Member-Variablen greifen die Player hoffentlich ohnehin nicht zu, sondern nur auf Get-Methoden der Timer-Klasse.

Damit kannst du mehrere Game-Objekte und mehrere Timer-Objekte erstellen - mehrere Timer könnten nützlich sein für Menü und den Spielfluss, die verschiedene Timer brauchen, mehrere Game-Objekte könnten z.B. in einem Level-Editor notwendig oder hilfreich sein, damit man mehrere Levels bearbeiten kann statt immer nur eins im Speicher haben zu können. Singletons wären da in jedem Fall die falsche Wahl.

Auch der Wunsch nach "von überall drauf zugreifen können" ist verständlich, aber sehr sehr schlechter Stil und Fehler im Design. Man sollte Objekte, die ein anderes Objekt braucht, immer an dieses übergeben und nicht wahlfrei quer durch die Klassen-Hierarchie Zugriffe erlauben.
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]

8

17.01.2012, 14:27

Super.. SUPER! Vielen Dank! Instanzenübergabe hat bestens funktioniert :D
Hmm und wenn ich mehrere Klassen in einer brauche dann übergebe ich einfach alle Instanzen die ich brauche.
Eventuell bekomme ich später Probleme im Design, falls das der Fall ist melde ich mich nochmal.

MfG Clark

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

9

17.01.2012, 14:48

das Problem an Designfehlern ist, dass sie der Person, die sie entwickelt hat, meist nicht oder nicht sofort auffallen
ich würde vorschlagen, du kannst dein Design in Form von UML-Klassendiagrammen darstellen und uns fragen, ob wir darin schwächen erkennen können
solltest du dich mit Klassendiagrammen bisher nicht auseinander gesetzt haben, so würde ich das empfehlen, vor allem, wenn du später in den Bereich der Softwareentwicklung gehen willst
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

10

18.01.2012, 21:11

Danke für deinen Tipp, das macht durchaus Sinn für mich. Denke dass ich es auch noch brauchen werde für mein Projekt und hier.
Hast du diesbezüglich einen Link? Ich werde schonmal googlen.

Ich habe nämlich jetzt ein Design Problem... ich versuche mal es zu schildern, bin leider noch nicht möglich UML Diagramme anzufertigen.

Ich habe 2 Klassen: Framework und Game.
In Framework erstelle ich Game und auch noch andere Zusatzklassen wie z.B. eine Klasse die Surfaces verwaltet etc. Aber wichtig ist folgende Idee:
Framework -> Game -> in Game erstelle ich später Spieler, Feinde etc einfach alles.

Ich muss jetzt um an die wichtigen Funktionen zu kommen eine Instanz von Framework an Game übergeben... selbst da würde man denken es ist schon schlecht Designt weil man dann eine Art endlos Addresse bekommt von Framework->Game.Framework->Game etc... denke ich. Vllt irre ich mich auch. ABER das Hauptproblem ist folgendes:

In Framework include ich Game.h und in Game.h ist nicht Framework.h included... geht auch nicht. Jetzt kann ich keinen Pointer cFramework* Framework mehr erstellen um in Game die Instanz zu speichern, weil es schlicht und ergreifend nicht definiert ist.

Wäre über jeden Vorschlag, Tipp oder Hilfe dankbar, falls ihr irgendwelche grundsätzlichen Muster habt wie man die "Grundpfeiler" eines Games strukturiert wäre das auch klasse, ich habe sowas leider nicht :pinch:

Werbeanzeige