Was ist richtig Weg, um ein statisches Element des Typs ‚T &‘ in einer Templat-Klasse zu initialisieren?
-
21-09-2019 - |
Frage
Ich spiele mit einem eifrigen initialisieren generic Singletonklasse um. Die Idee ist, dass man öffentlich von der Klasse erbt etwa so:
class foo : public singleton<foo> { };
Ich habe viel in dem Prozess gelernt, aber ich bin jetzt stecken, weil es mein Visual Studio 2008-Linker zu brechen. Das Problem ist mit dem statischen Instanz Mitglied und / oder seiner Initialisierung.
template<class T>
class singleton {
singleton();
singleton(singleton const &);
singleton & operator = (singleton const &);
public:
static T & instance;
};
template<class T> T & T::instance;
Jeder Einblick wäre sehr dankbar!
EDIT:
Mit dieser Klassendeklaration ...
template<class T>
class singleton {
singleton();
singleton(singleton const &);
singleton & operator = (singleton const &);
public:
static T instance;
};
template <class T> T singleton<T>::instance;
Wenn ich versuche, diese ...
zu tunclass foo : public singleton<foo> { };
ich diesen Fehler ...
Fehler C2248: 'Singleton :: singleton' : Kann private Member Zugang nicht in Klasse deklariert 'Singletons'
...
Diese Diagnose trat in der Compiler erzeugte Funktion 'foo :: foo (void)'
Meine Interpretation ist, dass Singletons will ein foo Objekt konstruieren, die durch Vererbung, hängt von der Konstruktion eines Singleton, dessen Konstruktor ist privat. I figured Singleton würde den Zugang zu ihrem eigenen Konstruktor hat, aber ich denke nicht. Irgendwelche Ideen?
EDIT 2:
Ich habe erkannt, dass der Ansatz von singleton<T>
vererben das Problem erfordert Änderung der Klasse verwendet als Singleton werden muss. Ich habe mit dem folgenden Code für meine eifrige initialisieren Singletonklasse Vorlage gelandet ist.
template<typename T>
class singleton_wrapper {
singleton_wrapper();
singleton_wrapper(singleton_wrapper const &);
singleton_wrapper & operator = (singleton_wrapper const &);
static T instance;
template<typename T> friend T & singleton();
};
template<typename T> T singleton_wrapper<T>::instance;
template<typename T>
T & singleton() {
return singleton_wrapper<T>::instance;
}
Für die Klasse ...
class foo {
public:
void bar() { }
};
... Man würde eine einzelne Instanz darauf zugreifen (initialisiert vor main ()) unter Verwendung der folgenden:
singleton<foo>().bar();
Nochmals vielen Dank für die Hilfe, vor allem GMan. Ich bin sehr zufrieden mit meiner ersten Erfahrung auf Stapel Überlauf .
Lösung
Sie können nicht, da Sie nicht über eine konkrete Instanz haben. Sie können benötigen eine aktuelle Instanz erstellen, dass Sie sich beziehen können:
template <class T>
class singleton {
...
private:
static T instance_;
public:
static T& instance;
};
template <class T> T singleton<T>::instance_;
template <class T> T& singleton<T>::instance = singleton<T>::instance;
oder einfach nur den Referenz Graben zusammen:
template <class T>
class singleton {
...
public:
static T instance;
};
template <class T> T singleton<T>::instance;
Andere Tipps
Off-the-Hülse. Wechsel Instanz sein vom Typ 'T' anstelle von 'T &'