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

ext

Treue Seele

  • Private Nachricht senden

11

09.06.2006, 12:54

Das Meyers-Singleton ist einfach zu handhaben und für einfache Zwecke vollkommen ausreichend.

Aber nehmen wir mal folgendes Beispiel:
Wir haben eine Log-Klasse die als Meyers-Singleton gebaut ist und eine Ressource-Manager-Klasse die als Meyers-Singleton gebaut ist. Im Destruktor von dem Ressource-Manager wird über die Log-Klasse ein paar statistische Infos ausgegeben (z.B. welche Ressourcen wie oft verwendet wurden, in welcher Reihenfolge, usw.). Damit das geht muss die Log-Klasse natürlich länger existieren als die Ressource-Manager-Klasse und diese Kontrolle gibt man beim Meyers-Singleton ab.

Lemming

Alter Hase

Beiträge: 550

Beruf: Schüler

  • Private Nachricht senden

12

09.06.2006, 13:41

ext
ein anderer punkt der mich dazu bewegt hat das mit zeigern zu machen ist folgender:
mal angenommen man hat in seinem spiel gamestates (intro, menu, game). die können alle zusammen ja schon ne mächtige menge member haben. trotzdem sind es objekte, die man sehr gut als singleton verwenden kann. denn mehr als ein game gleichzeitig mach idr einfach keinen sinn. wenn man die jetzt aber mit nem meyer singleton macht kann man sehr schnell sehr viel speicher verschwenden, weil während des spiels auch das intro und das menü immer noch existieren.
wenn man dagegen die kontrolle über die instanzierung hat, braucht man sich da keine stress zu machen....
Es gibt Probleme, die kann man nicht lösen.
Für alles andere gibt es C++...

alexm

Frischling

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

13

20.06.2006, 13:23

versteh ich das richtig, dass nix da's Singleton ohne new auskommt?
das heisst quasi, dass ich mir bei der getInstance() dann aussuchen kann,
ob ichs am stack oder am heap haben will - oder lieg ich komplett daneben?

C-/C++-Quelltext

1
2
3
4
5
debug MY_DEBUG_OBJECT = debug::getInstance();

// oder


debug * MY_DEBUG_OBJECT = new debug::getInstance();

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

14

20.06.2006, 13:27

Nein, der Singleton liegt immer auf dem Heap (als static Variable in einer Methode).

Du kannst dir aber beim Design der "GetInstance ()" Methode aussuchen, ob du einen Zeiger oder eine Referenz auf das Objekt haben möchtest. Eine Kopie eines Singleton gibt es nicht.

Damit funktionieren beide deiner Varianten nicht ;)
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

alexm

Frischling

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

15

20.06.2006, 13:41

:roll: äh und wie verwendet mann die dann? blick da momentan gar nicht dahinter ... sorry ... :cry:

Beliah

Treue Seele

Beiträge: 115

Wohnort: Söhlde - LK Hildesheim

Beruf: FI-Anwendungsentwicklung

  • Private Nachricht senden

16

20.06.2006, 14:55

Zitat von »"alexm"«

:roll: äh und wie verwendet mann die dann? blick da momentan gar nicht dahinter ... sorry ... :cry:

Was? Den Singleton? Die GetInstance() -Methode?
Debuggers don't remove bugs, they only show them in slow motion.

Google Suche ohne Werbung und Cookies: Scroogle

Derzeitige(s) Freizeitprojekt(e)

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

17

21.06.2006, 07:50

Also, das heisst, dass du dir als Rückgabewert der "GetInstance ()" Methode aussuchen kannst, ob du lieber einen Zeiger oder eine Referenz bekommen möchstest. also:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
CSingleton& CSingleton::GetInstance ()
{
  CSingleton instance;
  return instance;
}

/* oder */

CSingleton* CSingleton::GetInstance ()
{
  CSingleton instance;
  return &instance;
}


Die Methode mit der Referenz als Ergebnis ist dabei etwas netter, weil man dann z.B. recht einfach an überladene Operatoren rankommt. Mit dem Zeiger müsste man ja immer erst noch einmal dereferenzieren, was dann leicht in Klammerchaos ausartet. ;)

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

alexm

Frischling

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

18

21.06.2006, 10:17

Ist ja unglaublich, dass man anhand vom singleton sehr viel lernen kann. Find das cool! 8)

Ich verwende momentan folgenden Aufbau und hätte anschliessend dazu ne frage:



C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* cTimeManager.h */
class cTimeManager
{
private:

    static cTimeManager* m_ptrInstance;

    cTimeManager(){}                        // Konstruktor

    cTimeManager( const cTimeManager& );    // Kopierkonstruktor private, KEIN kopieren mehr möglich




public:

    static  cTimeManager*   CreateInstance();
    static  cTimeManager*   GetInstance();
    HRESULT                 Destroy();

    ~cTimeManager(){ Destroy(); }

};


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/* cTimeManager.cpp */
//-----------------------------------------------------------------------------

// STATIC Pointer auf einzige Objektinstanz

//-----------------------------------------------------------------------------

cTimeManager* cTimeManager::m_ptrInstance = NULL;

//-----------------------------------------------------------------------------

// Name: CreateInstance()

// Desc: Eine neue, einmalige Objektinstanz aus cTimeManager erstellen

//       Dient zur Initialisierung

//-----------------------------------------------------------------------------

cTimeManager* cTimeManager::CreateInstance()
{
    if( m_ptrInstance == NULL )
    {
        m_ptrInstance = new cTimeManager;
        // neue Instanz retour

        return m_ptrInstance;
    }
    // vorhandene Instanz retour

    return m_ptrInstance;
}

//-----------------------------------------------------------------------------

// Name: GetInstance()

// Desc: Aktuelle Objektinstanz zurückliefern

//       Dient zum vereinfachten Gebrauch -

//       Objektinstanz braucht nicht überall als Parameter übergeben werden

//-----------------------------------------------------------------------------

cTimeManager* cTimeManager::GetInstance()
{
    if ( m_ptrInstance )
    {
        return m_ptrInstance;
    } 
    else
    {
        return NULL;
    }
}

//-----------------------------------------------------------------------------

// Name: Destroy()

// Desc: Angeforderten Speicher sauber löschen

//-----------------------------------------------------------------------------

HRESULT cTimeManager::Destroy()
{
    // Speicherbereich mit 0 auffüllen

    // Pointer löschen

    // Point-to Adresse löschen

    if (m_ptrInstance)
    {
        SecureZeroMemory(&m_ptrInstance,sizeof(m_ptrInstance));
        delete m_ptrInstance;
        m_ptrInstance = NULL;
        return S_OK;
    }
    // Keine Objektinstanz zum löschen vorhanden

    // RETURN: Invalid_Pointer

    return E_POINTER;
}


Die Grundstruktur stammt aus meinem Buch
"Design Patterns - Elements of Reuseable Object-Oriented Software"
Dort wurde allerdings kein Destruktor implementiert.
Somit hab ich das ganze nach eigenem Ermessen ausgebaut und mein
Programm läuft zur zeit sehr stabil.

C-/C++-Quelltext

1
2
    static  cTimeManager*   CreateInstance();
    static  cTimeManager*   GetInstance();


... verwende ich zur besseren Übersicht.
Dachte mir, wenn ich nur GetInstance() verwende, lässt sich
a) später im code schwer herausfinden, wo die Objektinstanz
eigentlich erzeugt wird und
b) kann ich bei der CreateInstance() nach belieben Parameter für die
Initialisierung mitgeben, die ich dann natürlich bei GetInstance
nicht mehr brauche.

Allerdings stell ich mir die Frage, warum der ganze Aufwand mit den
Singletons. Wenn ich zB. eine Klasse mit lauter STATIC-Methoden
machen würde, hätts doch den selben effekt oder?

@rklaffehn
Danke! Jetzt blick ich da durch :)
Was mir an der Diskutierten Variante sehr gefällt ist, dass die ganz
und gar ohne NEW auskommt.
Lohnt es sich, meinen Code auf diese Variante anzupassen?
(hab inzwischen schon 11 Singletons in meiner Anwendung...)

Beliah

Treue Seele

Beiträge: 115

Wohnort: Söhlde - LK Hildesheim

Beruf: FI-Anwendungsentwicklung

  • Private Nachricht senden

19

21.06.2006, 10:46

Zitat von »"alexm"«


[...]
Allerdings stell ich mir die Frage, warum der ganze Aufwand mit den
Singletons. Wenn ich zB. eine Klasse mit lauter STATIC-Methoden
machen würde, hätts doch den selben effekt oder?
[...]


static-methoden haben den Nachteil das es kein this gibt und man somit auch nur auf statische Variablen zugreifen kann.
Das heißt, dass man auch alle Variablen statisch machen muss. Ich glaube da ist so eine statische getInstance- und destroy-Methode einfacher.

Vielleicht gibts auch noch andere Gründe, aber ich wüsste gerade keine.
Debuggers don't remove bugs, they only show them in slow motion.

Google Suche ohne Werbung und Cookies: Scroogle

Derzeitige(s) Freizeitprojekt(e)

alexm

Frischling

Beiträge: 71

Wohnort: Wien

  • Private Nachricht senden

20

21.06.2006, 10:52

Ja, aber das ist ja genau das, was mit dem singleton vernichtet wird -
this macht ja nur Sinn, wenn ich eben mehrere Instanzen habe,
um auf das jeweilige Member der Instanz zuzugreifen.
Durch das singleton hab ich ja nur eine Instanz und somit - wenn man
so will - würde auch die Verwendung von this immer auf die selbe
Instanz zugreifen.

Werbeanzeige