Singleton
-
PleaseHelpMe schrieb:
Verstehe deinen Beitrag nicht

1. Ein typisches Singleton lebt davon das nur eine Instanz existiert. Daher sollte die Schnittstelle auch auf eine Instanz ausgelegt sein, und gleichzeitig nicht unnöig verkompliziert werden.
class SingletonA { private: // Automatische generierung Kopierkonstruktor/Zuweisungsoperator // unterbinden... SingletonA(const SingletonA&); SingletonA& operator=(const SingletonA&); int xyz; SingletonA() : xyz(1) {} ~SingletonA() {} static SingletonA& get() { static SingletonA instance; return instance; } public: static foo() { get().xyz = 3; } };Sprich: Nach außen hin kenne ich Singletons als statische Klasse (nur statische Methoden sind öffentlich, die get()-Methode nicht). Dies ist auch einfacher, wieso solltest du die Instanz abfragen müssen um von einer einmaligen instanz die Methoden aufzurufen. Dann lieber eine statische Methode direkt zugreifen, die interne Verwaltung wird dabei einfach "verborgen", ein extra Aufruf von get ist außerhalb nicht nötig.
2. Wenn dein Destruktor knallt muss es ja bei der Freigabe des Objektes knallen. Zum Ende des Destruktors werden die Member, bei dir nur eine Map, destruiert. Daher würde ich zuerst mal schauen ob irgenein Fehler mit der map als solches existiert. Ich kenne diese SFML-Bibliothek nicht, daher könnte ich mir vorstellen, das es irgendwo mit dem Destruktor der Images zu tun hat. Manche Ressourcen können (wenn die Bibliothek nicht dafür ausgelegt ist) nicht einfach so destruiert werden, und es könnte vorher noch ein Aufruf wie z.B. xxx.Destroy() oder ähnliches nötig werden.
cu André
-
@PleaseHelpMe: Schonmal mit dem Debugger durchgegangen? Wenn ja, was sagt er?
-
Danke für deine Antwort

Also hier wäre die besagte Klasse sf::Image zu finden:
http://www.sfml-dev.org/documentation/classsf_1_1Image.htm
Ich finde dort jedoch keine Möglichkeit noch irgendetwas freizugeben...
Wie soll ich also nun vorgehen?
@Badestrand:
Es liegt definitiv am Dekonstruktor der Klasse Sprite(s. Oben).Ansonsten sagt er: Unbehandelte Ausnahme bei 0x004afb3b....
Zugriffsverletzung beim Lesen an Position 0x00000004.Dabei offenbart sich noch folgendes:
// TEMPLATE FUNCTION _Destroy template<class _Ty> inline void _Destroy(_Ty _FARQ *_Ptr) { // destroy object at _Ptr _DESTRUCTOR(_Ty, _Ptr); }Hilft euch das weiter?
Danke,
PleaseHelpMe
-
#include <SFML/Image.hpp> // brauchst doch nur sf::Image?! #include <string> #include <map> class ImageManager { typedef std::map<std::string, sf::Image> imagemap_t; ImageHolder imagemap_t; private: ImageManager() {} ImageManager(const ImageManager&); public: sf::Image& getImage(std::string const & fileName) { const imagemap_t::iterator it(images.find(fileName)); if (it != images.end()) return it->second; imagemap_t::iterator it (images.insert(std::make_pair(fileName, sf::Image())).first); it->second.LoadFromFile(fileName); return it->second; } public: inline static ImageManager& instance() { static ImageManager instance; return instance; } }; // ImageManager.instance().getImage("test.png"); /* oder wenn du den mehrmals hintereinander brauchst (Referenz): ImageManager& imageManager(ImageManager.instance()); imageManager.getImage("test01.png"); imageManager.getImage("test02.png"); */...
-
@ (D)Evil :
Dein Code erzeugt den gleichen Fehler. Ich habe es nun so gemacht, jedoch kann ich den Speicher nicht mehr freigeben:
class ImageManager { typedef std::map<std::string, sf::Image*> imagemap_t; imagemap_t images; private: ImageManager() {} ImageManager(const ImageManager&); ~ImageManager() { for (imagemap_t::iterator it = images.begin(); it != images.end(); it++) { delete (*it).second; // Ohne diese Zeile läuft es... } } public: sf::Image& getImage(std::string const & fileName) { const imagemap_t::iterator it(images.find(fileName)); if (it != images.end()) return *it->second; imagemap_t::iterator insertIt (images.insert(std::make_pair(fileName, new sf::Image())).first); (*insertIt->second).LoadFromFile(fileName); return *insertIt->second; } public: inline static ImageManager& instance() { static ImageManager instance; return instance; } };Ich finde das ziemlich unschön und ich habe bedenken, dass ich Speicherleaks bekomme. Andererseits scheint es nicht möglich zu sein den Speicher wieder freizugeben. Was soll ich tun? Ich bin mit meinem Latein am Ende

Danke,
PleaseHelpMe
-
Solange in dem Destruktor des zu löschenden Objekts eh nichts sinnvolles mehr abläuft (Was in Dateien schreiben, Datenbank updaten, etc.) wird der Speicher doch automatisch bei Beendigung des Programms (vom System) freigegeben.
-
Was ne beschissene Aussage @Fellhuhn. Weil irgendwer eh deine scheiße ausbaded, macht es nix wenn du welche verbockst oder wie?
@PleaseHelpMe: Hmm ... es liegt einfach an dem großen Nachteil von Singletons, (weshalb man dieses design pattern auch nicht nutzen sollte ...) dass nicht festgelegt ist, wann dein ImageManager objekt zerstört wird. Doch wird der Destruktor auf jedenfall nach dem Ende der main-Funktion aufgerufen. Also konkret:
sf::Image basiert auf sf::VideoResource. Diese ruft im Destruktor auf (vgl. http://www.sfml-dev.org/documentation/VideoResource_8cpp-source.htm):priv::GraphicsDevice::GetInstance().RemoveVideoResource(this);.
Dein priv::GraphicsDevice::GetInstance() objekt könnte aber bereits zerstört worden sein(die Wahrscheinlichkeit liegt bei 99.9%).
-
http://www.sfml-dev.org/documentation/classsf_1_1VideoResource.htm#dad15f792682bf766a2f199a3fad3c1d
Sieht so aus, als ob die Lib schon selber eine liste an resourcen führt, und evtl. zerstört. Bevor du das mit deinem Singelton machst.
-
(D)Evil schrieb:
Was ne beschissene Aussage @Fellhuhn. Weil irgendwer eh deine scheiße ausbaded, macht es nix wenn du welche verbockst oder wie?
Und wo ist der Unterschied zwischen
a) Programm sagt dem System "Speicher wird nicht mehr benötigt" und beendet sich
und
b) Programm beendet sich und System gibt den Speicher frei?
Solange in den Destruktoren keine Aktionen durchgeführt werden, ist es egal. b) dürfte sogar schneller sein.
-
Vielleicht löse ich mich einfach vom Singleton Konzept. Wobei ich dachte das es als Singleton sinnvoller wäre, da ich so nicht immer das Objekt weiterreichen muss etc.
Der Sinn hinter dieser Klasse soll ja sein das sofern ein Bild schon geladen wurde es nicht nochmal erneut sondern das schon geladene benutzt wird um Ressourcen zu sparen

Hättet ihr evtl. noch ein paar Ideen wie ich es ohne Singleton am Saubersten lösen kann? Würde mir sehr weiterhelfen.
Vielen Dank,