2010-12-16 15 views
0

ich zwei Klasse,Basisklasse Templat in C++

class CFoo 
{ 
    public: 
     static CFoo& GetInstance() 
     { 
     static CFoo instance; 
     return instance; 
     } 

     int GetValue(){ 
     return value; 
     } 

    private: 
     CFoo(){ 
     value = 0; 
     ltr = 'a'; 
     } 

     int value; 
     char ltr; 
}; 

class CBar 
{ 
    public: 
     static CBar& GetInstance(){ 
     static CBar instance; 
     return instance; 
     } 

     float GetValue(){ 
     return value; 
     } 

    private: 
     CBar(){ 
     value = 0.4; 
     ltr = 2; 
     } 

     float value; 
     int ltr; 
}; 

Ist es möglich, nur eine Klasse Vorlage für diese zwei Klassen zu erstellen, ist der Unterschied nur die Datentypen. Und da die Klasse ein Singleton ist, wie kann ich aufrufen, wenn ich eine Template-Klasse für diese zwei Klassen erstellen? Und geben Sie Beispielcode für die grundlegende Vorlagenklasse an.

Bitte um Rat.

Vielen Dank.

+1

Es ist eine seltsame Singleton-Implementierung, die bei jedem Aufruf von 'GetInstance()' eine neue Instanz zurückgibt. –

+0

@Fred Larson, das Instanzobjekt ist statisch, also wird es im Grunde nicht erstellt, wenn die Instanz noch nicht zerstört ist. – domlao

+1

Sie geben den Wert jedoch zurück, sodass Sie bei jedem Anruf eine Kopie zurückgeben. –

Antwort

6

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.

+0

Wie kann diese Vorlagenklasse oder die erstellte Instanz aufgerufen werden, da es sich um ein Singleton handelt? – domlao

+0

Was ist mit der Initialisierung der Mitgliedsvariablen? – sje397

+0

+1, besonders für die Empfehlung gegen Singleton. –

Verwandte Themen