static Variablen in Klassen-Templates möglich?



  • Hallo,
    ich versuche ein Klassentemplate zu erstellen in dem es static-Eigenschaften geben soll, die in jedem Objekt verfügbar sind, egal von welchem Typ.

    template <typename T>
    class AClass
    {
      public:
      T value;
      static int AnzahlKlassenObjekte;
    
      AClass(T value_)
      {
        value = value_;
        AnzahlKlassenObjekte++;
      }
    
      T getValue()
      {
        return value;
      }
    
      static int getNum()
      {
        return AnzahlKlassenObjekte;
      }
    };
    
    int main()
    {
      AClass<int> a(2);
      AClass<double> b(2.3);
      AClass<char> c('c');
    
      cout << "Klasse AClass wurde " << AClass::getNum() << "mal benutzt" << endl;
      return 0;
    }
    

    Dabei bekomm ich allerdings eine Fehlermeldung beim Kompilieren. Erstens lässt er mich nicht AClass::getNum() benutzen, sondern ich muss einen Typ angeben,
    z.B. AClass<int>::getNum(). Ich will aber eigentlich dass er in meinem Beispiel
    vom Typ unabhängig mitzählt wie oft AClass benutzt wurde.
    Und zweitens: selbst wenn ich AClass<int>::getNum() benutze bzw. wenn ich diese Zeile auskommentiere beschwert er sich in den Zeilen wo ich AnzahlKlassenObjekte inkrementiere, dass es eine "undefined reference to 'AClass<int>::AnzahlKlassenObjekte' ist.

    Weiss jemand Rat?
    Danke Uekue



  • Erstens: Jede Ausprägung des Templates ist eine eigenständige Klasse und hat eigenständige Member (inklusive der statischen Elemente). Das heißt auch, daß die Member AClass<int>::AnzahlKlassenObjekte, AClass<char>::AnzahlKlassenObjekte etc. nichts miteinander zu tun haben. Wenn du wirklich eine statische Variable für ALLE Aclass-Spezialisierungen haben willst, mußt du sie aus der Klasse auslagern:

    class Counter
    {
      static int Anzahl;
    public:
      Counter() {++Anzahl;}
      static int getNum() {return Anzahl;}
    };
    
    template<typename T>
    class AClass : public Counter
    {
      ...
    };
    
    ...
    AClass<int> a(0);
    AClass<char> b('0');
    
    cout<<"Es gibt "<<Counter::getNum() /*oder auch a.getNum()*/ <<" Objekte";
    

    Zweitens: Für Statische Member mußt du noch extra Speicherplatz anbieten, indem du einmalig ein int Counter::Anzahl=0; in dein Porgramm reinpackst.



  • Hi,
    Müll ( Thx CStoll )

    nd zweitens: selbst wenn ich AClass<int>::getNum() benutze bzw. wenn ich diese Zeile auskommentiere beschwert er sich in den Zeilen wo ich AnzahlKlassenObjekte inkrementiere, dass es eine "undefined reference to 'AClass<int>::AnzahlKlassenObjekte' ist.

    Statische Elemente müssen auch noch definiert werden. Pack das einfach unter deine Klasse:

    template <typename T>
    int AClass<T>::AnzahlKlassenObjekte = 0;
    


  • KasF schrieb:

    Hi,
    Müll ( Thx CStoll )

    Nein, CStoll hat recht mit dem Basisklassencounter.

    Der OP möchte dass sich _ALLE_ Templateinstanzen den Counter teilen.

    Grüsse

    *this



  • Wenn er unrecht hätte, hätte ich nicht Thx geschrieben 🙂
    Ich hatte da Müll stehen 😉 Ist mir eingefallen als ich CStolls Post gelesen haben ( gut das das keiner gesehen hat *OmanOman* )



  • Perfekt, danke!
    Habs jetzt mit ner Hilfsklasse gemacht und dann braucht man wirklich noch die explizite Deklaration! Aber jetzt gehts!


Anmelden zum Antworten