too few template-arguments-lists
-
Wäre es nicht schöner, wenn es
static T* Instance; static T* getInstance(){ if(!Instance){ Instance = new T(); } return Instance; }heißen würde?
-
Michael E. schrieb:
Wäre es nicht schöner, wenn ...
Damit könntest du Recht haben
Hab den Code entsprechend angepasst.
-
pumuckl schrieb:
Allgemein wirst du für alle anderen Instantiierungen von A aber dann noch den Fehler erhalten "undefined reference to A<C>::Instance" - weil du Instance eben nur für B definiert hast und für alle anderen möglichen Templateparameter nicht. Um das zu beheben könntest du einfach allgemein A<T>::Instance = NULL in A.hpp schreiben (hier in die hpp, weils ein Template und keine vollständige Spezialisierung ist). Die Spezialisierung für B kann dann entfallen.
Ich habe diesen Vorschlag nun ausprobiert, da er meiner Meinung nach die sinnvollste und sauberste Lösung darstellt:
// Datei A.hpp template <class T> class A{ private: static A<T>* Instance; // Ctor und Copy-Ctor public: static A<T>* getInstance(){ if(!Instance){ Instance = new T(); return Instance; } return Instance; } protected: // Irgendwelche Schnittstellendefinitionen }; A<T>::Instance = NULL;Aber anschließend bekomme ich immer wieder die Fehlermeldung, dass "T" in diesem Gültigkeitsbereich nicht definiert wurde(mit Verweis auf die Zeile 19). Wie nehme ich nun die Initialisierung für Instance vor, ohne das Template spezialisieren zu müssen?
-
Wie wäre es mit:
template<typename T> A<T>* A<T>::Instance = NULL;Aber sag mal, bist du sicher, dass es eine
A<T>Instanz sein soll und nicht gleich eineTInstanz?Und wieso machst du dir das Leben nicht einfacher und machst sowas:
// Datei A.hpp template <class T> class A{ // Ctor und Copy-Ctor public: static A<T>* getInstance(){ static A<T>* Instance = new T(); return Instance; } protected: // Irgendwelche Schnittstellendefinitionen };Falls das Objekt nicht zu gross ist, könntest du es sogar direkt bauen lassen und nicht über den Heap gehen:
static A<T>& getInstance(){ static T Instance; return Instance; }Grüssli
-
Hi,
Dravere schrieb:
Wie wäre es mit:
template<typename T> A<T>* A<T>::Instance = NULL;Jupp, funktioniert, danke. Und ich hatte mich tatsächlich die ganze Zeit gefragt, warum T undefiniert ist

Hier würde es tatsächlich auch reichen, nur eine Instanz vom Typ T zurückzugeben. Habs entsprechend geändert.Dravere schrieb:
Und wieso machst du dir das Leben nicht einfacher und machst sowas:
// Datei A.hpp template <class T> class A{ // Ctor und Copy-Ctor public: static A<T>* getInstance(){ static A<T>* Instance = new T(); return Instance; } protected: // Irgendwelche Schnittstellendefinitionen };Hmm, wenn ich an dieser Stelle getInstance() zweimal aufrufe, was passiert dann mit dem ersten - auf dem Heap angelegten - T? Ich könnte dann doch theoretisch folgendes machen:
typedef A<T> Singleton; static Singleton* foo = Singleton::getInstance(); static Singleton* bar = Singleton::getInstance(); // 2 verschiedene Instanzen von SingletonVielleicht ist es aber schon zu spät, und ich raffe es nicht

-
Nein, statische Initialisierungen passieren nur einmal pro Programmdurchlauf.
Aber wieso auf dem Heap? Wer soll das dann freigeben? Ausserdem würde ich keinen Zeiger, sondern eine Referenz zurückgeben.
-
Nexus schrieb:
Nein, statische Initialisierungen passieren nur einmal pro Programmdurchlauf.
Okay, ich war gerade in dem Glauben, dass eine neue statische Variable innerhalb der Funktion generiert wird, was sich jetzt nach mehrmaliger Überlegung natürlich als falsch herausstellt

Nexus schrieb:
Aber wieso auf dem Heap? Wer soll das dann freigeben? Ausserdem würde ich keinen Zeiger, sondern eine Referenz zurückgeben.
In meinem Quellcode versteckt sich noch eine kleine statische Memberfunktion destroy(), die den Speicher am Ende des Programms wieder freigibt.

-
Matzer schrieb:
In meinem Quellcode versteckt sich noch eine kleine statische Memberfunktion destroy(), die den Speicher am Ende des Programms wieder freigibt.

Sehr heikel, sowas geht extrem schnell vergessen. Gerade wenn das Programm frühzeitig beendet wird und das Projekt wächst. Wieso nicht direkt im statischen Speicherbereich arbeiten oder wenigstens den Zeiger kapseln?
Ach ja, Referenzen fände ich immer noch besser.

Hat es einen bestimmten Grund, wieso du Zeiger nimmst? Wenn du dauernd dereferenzierst, kann eine Referenz schöner sein. Aber ist auch ein wenig Geschmackssache...
-
Nexus schrieb:
Matzer schrieb:
In meinem Quellcode versteckt sich noch eine kleine statische Memberfunktion destroy(), die den Speicher am Ende des Programms wieder freigibt.
Sehr heikel, sowas geht extrem schnell vergessen. Gerade wenn das Programm frühzeitig beendet wird und das Projekt wächst. Wieso nicht direkt im statischen Speicherbereich arbeiten oder wenigstens den Zeiger kapseln?Momentan schreibe ich an einer GUI-Lib und um boost::asio dazu zu überreden, einen asynchronen Aufruf zu meinem globalen EventHandler zu starten, muss am Ende jedes Programms ungefähr sowas stehen:
// irgendwo im Code boost::asio::io_service MsgHandler; //in main() MsgHandler.run(); return 0;Natürlich ist der Aufruf von run in irgendeiner Klasse gekapselt. Da aber run() am Ende des Programms sowieso ausgeführt werden muss, übernimmt die kapselnde Klasse anschließend auch die Aufräumarbeiten, sobald die globale MessageLoop durchlaufen ist. Vergessen wird es also erstmal nicht

Nexus schrieb:
...oder wenigstens den Zeiger kapseln?
kommt alles noch
Ich wollte es erstmal schaffen, auf Linux und Windows je ein Fenster zur Anzeige zu bringen (was mir vorhin auch gelungen ist muhaa). Deswegen wird in einigen Teilen des Codes noch mir rohen Zeigern rumhantiert. Ich wollte nur so schnell wie möglich zum Ziel. Das geht natürlich auf Kosten des DesignsNexus schrieb:
Ach ja, Referenzen fände ich immer noch besser.

Hat es einen bestimmten Grund, wieso du Zeiger nimmst? Wenn du dauernd dereferenzierst, kann eine Referenz schöner sein. Aber ist auch ein wenig Geschmackssache...
Der hartnäckigen Forderung nach einer Referenz werde ich natürlich nachkommen
Ist an dieser Stelle wohl tatsächlich angebrachter.
-
Würd dir empfehlen, dieses buch zu holen:
http://www.amazon.com/Modern-Design-Programming-Patterns-Depth/dp/0201704315
Da gibt es ein größeres beispiel zu einer modernen gui lib, afaik. Falls es mal irgendwo hapert.