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

13.05.2012, 16:50

Listing 12.2 CTimer::Get()

Hallo zusammen,

ich bin jetzt im letzten Kapitel des Buchs (C++ für Spieleprogrammierer) angelangt.

Nun verstehe ich diesen Abschnitt nicht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef TIMER_HPP
#define TIMER_HPP

#include <SDL.h>
#include "singleton.hpp"

#define g_pTimer CTimer::Get()
class CTimer : public TSingleton<CTimer>
{
...
};

#endif


Meine erste Frage ist was genau wird bei #define CTimer_HPP deklariert?

Außerdem ist mir trotz mehrmaligem Lesen des Singleton Abschnitts nicht klar
wie hier #define g_pTimer CTimer::Get() auf eine Klasse zugegriffen wird von
der noch keine Instanz erzeugt wurde und warum nicht explizit angegeben wird
dass hier ein Zeiger, g_pTimer erstellt wird (wird er das überhaupt? ?( ).

Vielen Dank schon im Voraus für eure Antworten.

h3nryjk

Frischling

Beiträge: 13

Wohnort: 127.0.0.1 - Mi casa es tu casa

Beruf: Student

  • Private Nachricht senden

2

13.05.2012, 17:12

Hey Beorn,

soweit ich das verstehe handelt es sich hier um eine Singleton-Klasse.
Am besten schaust du dir dazu den Wikipedia-Eintrag an:
http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)

Ein Singleton ist im Grunde genommen eine Klasse, von der es nur ein Objekt
gibt, welches allerdings nicht direkt Instantiiert werden kann, da der Konstruktor
privat ist. Stattdessen wird eine Methode verwendet, die ungefähr so aussehen könnte:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
private:
static Singleton* instance;

...

public:
static Singleton getInstance() {
    if (instance == null) {
        instance = new Singleton();
    }
    return instance
}


Verwendet wird das ganze folgendermaßen:

C-/C++-Quelltext

1
2
3
4
...
Singleton.getInstance().doSomething();
Singleton.getInstance().doSomethingElse();
...



C-/C++-Quelltext

1
#define g_pTimer CTimer::get()


soll es dem Programmierer erleichtern, sich die Instanz des Singletons zu holen.


Das "TIMER_HPP" wird am Anfang definiert, da es zum sogenannten Guard gehört.
Ein Guard schützt die Header-Datei davor, dass sie beim mehrfachen Einbinden immer wieder
neu "ausgeführt" (?) wird. Ansonsten würde die Klasse CTimer mehrfach angelegt - es käme
also wahrscheinlich zu einem Compiler-Fehler.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »h3nryjk« (13.05.2012, 19:05)


3

13.05.2012, 18:43

Vielen Dank für die schnelle Antwort!

Das mit #define TIMER_HPP ist mir jetzt klar :thumbsup:

Allerdings verstehe bei der Anwendung des Singletons
in dieser Situation #define g_pTimer CTimer::Get()
nicht wie hier auf die Klasse CTimer zugegriffen werden kann
wenn weder eine Instanz noch eine Definition vorliegt.
Der genaue Quellcode ist in meinem ersten Post zu sehen.

h3nryjk

Frischling

Beiträge: 13

Wohnort: 127.0.0.1 - Mi casa es tu casa

Beruf: Student

  • Private Nachricht senden

4

13.05.2012, 19:04

Von einem Singleton lääst sich keine Instanz durch

C-/C++-Quelltext

1
Singleton s;

erstellen.
Stattdessen kann man sich nur eine Instanz von der Singleton Klasse über eine
statische Methode, in diesem Fall CTimer::Get(), holen. Statische Methoden haben die Eigenschaft, dass sie
auch ohne Instantiierung einer Klasse aufgerufen werden können.

C-/C++-Quelltext

1
CTimer::Get()

kann also auch aufgerufen werden, ohne dass eine Instanz erzeugt wird.

5

13.05.2012, 21:06

Achso^^

Jetzt hab ich endlich alles verstanden.

Vielen Dank!!!

TigerClaw25

unregistriert

6

04.04.2013, 19:16

Der Beitrag hat mir geholfen. Das bedeutet, dass singletons nur dann verwendet werden, wenn wir nur eine Instanz einer Klasse benoetigen und in dem. Fall die Klasse selbst. Der vorteil liegt dann darin, dass man keine wirkliche Instanz braucht ala CTimer Instanz1 sondern ueber die Funktion direkt die Klasse verwenden,uebergeben oder sonst wie was damit machen kann.

Ist das soweit korrekt?

was das define betrifft so steht das ausserhalb der klasse, dadurch kannst du es innerhalb jeder anderen Klasse verwenden, denke ich mal

MGBeginner

Frischling

Beiträge: 81

Wohnort: Limburg

  • Private Nachricht senden

7

04.04.2013, 20:33

Ja, dass hast du schon fast richtig verstanden. Eine Instanz gibt es aber schon, die wird aber nicht von dir erzeugt, sondern die Klasse erzeugt diese einzige Instanz quasi selbst (entweder schon bei Start des Programms oder wenn das 1. Mal eben diese Get - Methode aufgerufen wird - es gibt verschiede Implementierungen von Singletons !)

Hier sei aber nochmals darauf hingewiesen, dass die Verwendung von Singletons bei vielen nicht gern gesehen ist, dazu gab es in diesem Forum ja schon eine Menge Diskussionen, du kannst ja dazu mal im Froum nach früheren Beiträgen suchen, damit die Diskussion hier nicht wieder losgeht.

TigerClaw25

unregistriert

8

04.04.2013, 21:27

as Thema ist garnicht so einfach. Wenn CTimer von der Singletonetemplate erbt, kann ich direkt ueber CTimer die Funktion Get aufrufen. Verwende ich dann ueber diese eine Instanz dann die eigentliche Klasse CTimer ???

Verstehe am Beispiel oben nicht, wie das genau ablaeuft. CTimer::Get bedeutet, dass ein Objekt erzeugt wird.
Also im Grunde rufe ich ueber dieses Vererben eine Zeile tiefer die Funktion Get() auf und habe mein Objekt vom Typ CTimer.

Dieses kann ich dann verwenden ...

EDIT: Habe es mittlerweile versdtanden. In der Singleton Klasse gibt es eine Funktion geht, die dafür sorgt, dass eine Instanz der Klasse erstellt wird ... Dann erbt die Klasse CTimer von der Singleton Klasse. Per CTimer::Get() wird dann ein einziges Objekt erzeugt, die Get() funktion sorgt dabei dafür, dass bei weiterer Verwendung keine weiteren Objekte erstellt werden.

Will man nun auf CTimer zugreifen, z.B auf Memberfunktionen, dann einfach per CTimer::Get()->FunktionderKlasse(); , da Get() einen Zeiger auf die Klasseninstanz (Einmaliges Objekt) zurück gibt.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TigerClaw25« (04.04.2013, 22:46)


TigerClaw25

unregistriert

9

05.04.2013, 10:57

Ist es eigentlich erlaubt eine Zeiger von einer Klasse in eine andere zu kopieren? Die Klasse Framework enthält den m_pScreen Zeiger, dieser wird ja beim Aufruf der Klasse Sprite durch eine Singleton m_framework->Get(); (Funktion gibt Zeiger zurück) kopiert oder zugewiesen ...

Gibt es noch andere Varianten? Bin etwas verwirrt ...

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

10

05.04.2013, 11:03

Genereller Tipp: Vermeidet Singletons und verbannt die Gedanken daran. Das Pattern ist so gut wie nie hilfreich, auch wenn es am Anfang manchmal so scheinen mag.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Werbeanzeige