Nur ein Objekt
-
Hallo,
kann man es irgendwie realisieren, dass ich eine Klasse habe und von dieser
Klasse nur ein Objekt erschaffen werden darf?Danke im Voraus!!!
-
jap, Stichwort Singleton
-
Hab es mir mal bei Wikipedia ein bisschen durchgelesen. Das ist genau das was
ich brauche
!!! Ich wusste gar nicht, dass man Konstruktor in private ein-
packen kann! Das verhindert dann, das noch ein Objekt erzeugt wird, aber kann
man dann schon noch EIN Objekt erzeugen???
-
Du hast die statische Instanz (Pointer, mit 0 initialisiert) und die statische Methode getInstance die ein neues Objekt erzeugt (mittels des privaten Konstruktors) sollte der Pointer noch 0 sein und sonst diesen nur zurückgibt.
-
Wenn Du Konstruktor, Copy-Konstruktor und Zuweisungsoperator private machst, dann kann man von außen keine Objekte davon erstellen.
Nur innerhalb der Klasse selbst können Objekte der Klasse erzeugt werden.
Weil es aber nur eines sein soll wird auch nur eins erstellt und nach außen hin dieser, über eine Statische Methode, verfügbar gemacht.
-
Ah! Jetzt verstehe ich's! Danke!

-
dumme Frage, ich weiß jetzt nicht, warum das schlecht sein soll, aber, warum sollte man es nicht so machen:
class Singleton { private: static Singleton * m_singletonInstance; Singleton() { /* do your stuff */ } public: static Singleton & getInstance () { return *m_singletonInstance; } }; Singleton * Singleton::m_singletonInstance = new Singleton();Ich meine, wenn man ein Singleton hat, wird man es auf jeden Fall verwenden wollen, d.h. ich sehe keine Vorzüge, die Instanz erst bei "Bedarf" anlegen zu müssen.
Abgesehen davon ist das Erzeugen in getInstance() zum Beispiel, wenn man es nicht irgendwie absichert, nicht threadsafe.
-
Vorden schrieb:
Ich meine, wenn man ein Singleton hat, wird man es auf jeden Fall verwenden wollen, d.h. ich sehe keine Vorzüge, die Instanz erst bei "Bedarf" anlegen zu müssen.
Dein eigenes Beispiel wird ggf. auch erst mit der ersten Benutzung initialisiert (Oder nenne mir eine Stelle des C++ Standards die meiner Aussage wiederspricht). Bei globalen Variablen (die dafür aber in einer undefinierten Reihenfolge initialisiert werden) ist dies anders.
cu André
-
Eine Frage: Wo rufst du den Destruktor auf?
Meyer'sche Singleton:
template <class class_type> class singleton { singleton(singleton const&); singleton& operator=(singleton const&); singleton(); ~singleton(); public: inline static class_type& instance() { static class_type instance; return instance; } }
-
ob es bei ansi c++ jetzt wenn man es genau so schreibt erst bei der ersten benutzung initialisiert wird oder nicht ist doch egal
vllt wird es in java, c++/cli, c#, etc. ja bereits sofort angelegt, das design pattern ist dasselbeich finde nichts schlechtes daran es direkt anzulegen anstatt in der GetInstance() methode ein
if(instance == NULL) instance = new Singleton();wenn dein singleton ein bitmap manager ist zb in einem zeichenprogramm und du ihn allein schon bei der initialisierung der GUI verwendest und sowieso 100% wenn man das programm benutzt, klar wieso nicht
der einzige fall wo ich die if abfrage machen würde und erst das singleton initialisieren würde wenn ich es zum ersten mal brauche wäre wenn es sich um was "großes" handelt
beispielsweise ein singleton networkking betreibt und erst zu einem server connected und eine connection aufbaut mit der er die daten hin und her schickt weil sie nicht lokal gemanaged werden
dann macht es natürlich sinn ihn erst anzulegen wenn man ihn benötigt
also bei objekten wo das anlegen viel aufwand dastellt, vllt eine statische Initialize() methode die einmal das objekt erstellt
es kommt immer auf den scope an in dem man sowas programmiert
-
naja, wenn man das Ganze in eine Art Smartpointer wrappt geht es ohne Probleme, dann wird ja der Destruktor implizit spätestens beim Schließen des Programmes aufgerufen (jedenfalls der des Smartpointers) und dieser wiederum zerstört die Singleton-Instanz. z.B.:
class SP; class Singleton { friend class SP; private: static SP singleton; public: static Singleton & getInstance (); }; class SP { Singleton * instance; public: SP(): instance( new Singleton() ) {} Singleton * operator * () { return instance; } ~SP() { delete instance; } }; SP Singleton::singleton; Singleton & Singleton::getInstance() { return *(*singleton); }So gehts auch wunderbar und der Destruktor wird sogar aufgerufen
-
Äh, ich habe noch mal eine Frage zu den SingleTon.
Auf folgender Seite:
http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)Bei den Beispielen in C++. Wie kann ich jetzt das eine Objekt erzeugen???
-
In dem du
Singleton::getInstance()verwendest. Da es eine statische methode ist kannst du sie ohne Objekt verwenden.
Schau auch mal hier
http://www.oop-trainer.de/Themen/Singleton.html
-
Naja das der Destruktor nicht aufgerufen wird ist sowieso total schnuppe. Alle Resourcen werden bei Programmende, sofern das Betriebssystem nicht total auf den Kopp gefallen ist, zurückgegeben.
Wenn man sowas als "schlechten Stil" bezeichnet, kann man immer noch eine DestroySingleton() Funktion machen oder anstatt newstatic singleton singleton::instance = singleton();machen. Das läuft allerdings fast auf das selbe wie oben hinaus.
-
c++-er schrieb:
Naja das der Destruktor nicht aufgerufen wird ist sowieso total schnuppe. Alle Resourcen werden bei Programmende, sofern das Betriebssystem nicht total auf den Kopp gefallen ist, zurückgegeben.
Dies stimmt so nicht ganz, kommt immer darauf an was es für Ressourcen sind. Zumal ein new an der Stelle sowas von unnötig ist und es mit einem Objekt ohne all diese Probleme geht.
c++-er schrieb:
Wenn man sowas als "schlechten Stil" bezeichnet, kann man immer noch eine DestroySingleton() Funktion machen oder anstatt new
static singleton singleton::instance = singleton();machen. Das läuft allerdings fast auf das selbe wie oben hinaus.
Eben nicht. Und ja es ist "schlechten Stil" und auch eine DestroySingleton()-Funktion geht an dem Sinn und Zweck eines Singletons vorbei.
Mag es dir vielleicht kleinkariert erscheinen, wenn du wie ich an einer "historisch gewachsenen Anwendung" arbeitest, bist du froh möglichst viele Fallstricke zu vermeiden. Es reicht schon das noch genügend "historische Altlasten" in der Software sind, und durch Zeitdruck und mangelde Planung das ganze noch verschärft wird.
cu André
-
asc schrieb:
... geht an dem Sinn und Zweck eines Singletons vorbei.
Dann erklär mir mal den Sinn und Zweck eines Singleton. Wenn ich nur eine Instanz haben will dann lege ich nur eine Instanz an. Deshalb ein Singleton zu benutzen ist total schwachsinnig(meine Meinung!). Außerdem bindet man sich (bei großen Projekten) mittel-/langfristig mit Singletons einen riesigen Klotz ans Bein. Man läuft einfach Gefahr das man soviel Querverstrebungen hat, dass man nicht mehr weiß wo hinten und vorne ist und dies macht die Wartung einfach ungeheuer schwierig.
-
c++-er schrieb:
asc schrieb:
... geht an dem Sinn und Zweck eines Singletons vorbei.
Dann erklär mir mal den Sinn und Zweck eines Singleton.
Mein "geht am Sinn und Zweck" vorbei bezieht sich auf dein DestroySingleton(). Wenn man schon ein Singelton einsetzt, so weiß man meist nicht wann man den letzten Zugriff hat. Daher ist es unsinnig sich um die Freigabe kümmern zu müssen (Sprich Fehlerhafte Implementierung des Singletons).
c++-er schrieb:
Wenn ich nur eine Instanz haben will dann lege ich nur eine Instanz an. Deshalb ein Singleton zu benutzen ist total schwachsinnig(meine Meinung!).
Gut, dann sag mir mal wie du auf diese eine Instanz zugreifen willst. Wenn du sie überall durchreichst, okay. Aber nehmen wir mal an du hast z.B. Allgemeine Einstellungen zu deiner Anwendung die nur einmal eingelesen werden müssen. Ich sehe hier eben den Sinn des Singletons das diese - bei der ersten Anfrage der Einstellung - eingelesen werden, und anschließend bereit stehen. Da die Einstellungen an mehreren Stellen verwendet werden, kann man nicht genau sagen wann sie nicht mehr verwendet werden. Ein Singleton räumt sich selber auf.
c++-er schrieb:
Außerdem bindet man sich (bei großen Projekten) mittel-/langfristig mit Singletons einen riesigen Klotz ans Bein. Man läuft einfach Gefahr das man soviel Querverstrebungen hat, dass man nicht mehr weiß wo hinten und vorne ist und dies macht die Wartung einfach ungeheuer schwierig.
Nenn mir eine sinnvolle Alternative für mein Beispiel mit den Programmeinstellungen. Eine globale Variable ist es nicht (Die hat zudem den Nachteil der ungewissen Anlagereihenfolge), die Übergabe an jedes Objekt ist es mit Sicherheit auch nicht.
Ja, man sollte nicht mit Singletons übertreiben. Aber einen Sinn und Zweck haben sie schon.
cu André
-
Komplett statische Klassen wären eine Möglichkeit, sind aber nicht so flexibel zu erweitern, sollte man mal mehrere Instanzen benötigen. Auch sind sie nerviger zu schreiben.