Wenn Sie ähnliche Klassen wie diese verallgemeinern möchten, können Sie dies im Allgemeinen tun, indem Sie alle Typen durch Typparameter ersetzen. So würden Sie hier beispielsweise einen Typparameter für den Typ value
und einen Typparameter für den Typ ltr
deklarieren.
Das sieht natürlich so etwas wie:
template <typename ValueT, LtrT>
class C
{
// ...
};
Dann ist es nur eine Frage der konkreten Typen in der Klasse mit den Typparametern ersetzt so value
und ltr
würde (innerhalb der Klasse deklariert werden Template-Definition):
ValueT value;
LtrT ltr;
um diese Klassenvorlage zu machen leichter nutzbar, einige typedefs erstellen (außerhalb der Klasse Template-Definition):
typedef C<int, char> CFoo;
typedef C<float, int> CBar;
Sie benötigen auch eine Möglichkeit, die Elementvariablen zu initialisieren. Ihre beste Wette ist der Konstruktor nehmen Argumente, mit denen zu machen, die Elementvariablen initialisiert werden (innerhalb der Klasse Template-Definition):
C(const ValueT& initial_value, const LtrT& initial_ltr)
: value(initial_value), ltr(initial_ltr) { }
Da Sie versuchen, einen Singleton zu verwenden, wird dies mit dem aktuellen nicht funktionieren (gebrochene) Implementierung von GetInstance()
, weil die Funktion-Scope-Static im Funktionskörper initialisiert werden muss. Sie können, indem er erklärt die Singleton-Instanz als statische Klassenvariable (innerhalb der Klasse Template-Definition) um diese Arbeit:
C singleton;
dann müssen Sie diese Dateien in einem Ihrer Quelle definieren und zu initialisieren; müssen Sie eine Definition für jede Instanziierung C
, mit dem Sie haben, also für die beiden Sie hier haben, würden Sie brauchen:
template<> CFoo CFoo::singleton(0, 'a');
template<> CBar CBar::singleton(0.4, 2);
Wenn Sie das alles zusammen, wird es so etwas wie dieses (I‘aussehen ve dumbed es nur eine einzige Art und Wert für die der Kürze halber verwenden unten):
template <typename T>
struct S
{
public:
S(const T& initial_value) : value(initial_value) { }
const T& GetValue() const { return value; }
static const S& GetInstance() { return singleton; }
private:
// since it's a singleton, make it noncopyable
S(const S&);
void operator=(S);
T value;
static S singleton;
};
typedef S<int> SInt;
template<> SInt SInt::singleton(42);
int main()
{
int value = SInt::GetInstance().GetValue();
}
Schließlich und vor allem beachten sie bitte nicht ein Singleton verwenden. Singletons sind fast immer eine schlechte Idee. Es ist unmöglich zu sagen, was Sie aus Ihrem abgespeckten Beispiel erreichen wollen, aber Sie sollten auf jeden Fall versuchen, einen anderen Weg zu finden.
Es ist eine seltsame Singleton-Implementierung, die bei jedem Aufruf von 'GetInstance()' eine neue Instanz zurückgibt. –
@Fred Larson, das Instanzobjekt ist statisch, also wird es im Grunde nicht erstellt, wenn die Instanz noch nicht zerstört ist. – domlao
Sie geben den Wert jedoch zurück, sodass Sie bei jedem Anruf eine Kopie zurückgeben. –