1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Eigene Templateklasse schreiben

  • Blixa Barscheck
  • 29. August 2007 um 15:27
  • Unerledigt
  • Blixa Barscheck
    12
    Blixa Barscheck
    Mitglied
    Reaktionen
    11
    Punkte
    1.406
    Beiträge
    229
    • 29. August 2007 um 15:27
    • #1

    Geg. sind folgende Dateien:

    Code
    // Personenverwaltung.h
    
    
    template<class T>
    class Personenverwaltung{
    
    
    public:
    
    
        T arr[3];
    
    
        bool isSorted();
    
    
        int compare(T t, int i);
    
    
        T get(int i);
    };
    Alles anzeigen
    C
    // Personenverwaltung.cpp
    
    
    #include "Personenverwaltung.h"
    
    
    bool Personenverwaltung<class T>::isSorted(){
    
    
        for(int i = 0; i < 2; i++){
            if(arr[i] > arr[i+1]){
                return false;
            }
        }
    
    
        return true;
    }
    
    
    int Personenverwaltung<class T>::compare(T t, int i){
    
    
        if(arr[i] > t)    return 1;
    
    
        return 0;
    }
    
    
    T Personenverwaltung<class T>::get(int i){
    
    
        return arr[i];
    }
    Alles anzeigen
    C
    // main.cpp
    
    
    #include <iostream>
    #include <string>
    #include "Personenverwaltung.h"
    
    
    using namespace std;
    
    
    
    
    class Person{
    
    
    public:
    
    
        Person(){}
    
    
        string name;
    
    
        Person(string name){
            this->name = name;
        }
    
    
        bool operator>(Person& p){
            return name.compare(p.name) > 0;
        }
    };
    
    
    int main(){
    
    
    
    
        Person p_0("Mueller"); Person p_1("Schreiner");    Person p_2("Gehrer");
        Person p("Faerber");
    
        Personenverwaltung<Person> pv;
    
    
        pv.arr[0] = p_0;
        pv.arr[1] = p_1;
        pv.arr[2] = p_2;
    
    
        cout << pv.isSorted() << endl;
    
    
        cout << pv.compare(p,1) << endl;
    
        cout << pv.get(2).name << endl;
    
    
        return 0;
    }
    Alles anzeigen

    und die daraus resultierende Fehlerausgabe

    Code
    Personenverwaltung.cpp
    personenverwaltung.h(8) : error C2148: Gesamtgröße des Arrays darf 0x7fffffff Bytes nicht übersteigen.
            personenverwaltung.cpp(5): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "Personenverwaltung<T>".
            with
            [
                T=T
            ]
    personenverwaltung.h(8) : error C2079: 'Personenverwaltung<T>::arr' verwendet undefiniertes class 'T'
            with
            [
                T=T
            ]
    personenverwaltung.cpp(8) : error C2036: 'T *': Unbekannte Größe
    personenverwaltung.cpp(8) : error C2036: 'T *': Unbekannte Größe
    personenverwaltung.cpp(8) : error C2676: Binärer Operator '>': 'T' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht
    personenverwaltung.cpp(8) : error C2036: 'T *': Unbekannte Größe
    personenverwaltung.cpp(8) : error C2676: Binärer Operator '>': 'T' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht
    personenverwaltung.cpp(23) : error C2027: Verwendung des undefinierten Typs "T"
        personenverwaltung.cpp(5): Siehe Deklaration von 'T'
    personenverwaltung.cpp(23) : error C2079: 'Personenverwaltung<T>::get' verwendet undefiniertes class 'T'
            with
            [
                T=T
            ]
    personenverwaltung.cpp(25) : error C2036: 'T *': Unbekannte Größe
    Alles anzeigen

    Mach ich die Implementierung 'inline' und geb alles in eine Datei, funktioniert alles:

    C
    // main_inline.cpp
    
    
    #include <iostream>
    #include <string>
    
    
    using namespace std;
    
    
    
    
    class Person{
    
    
    public:
    
    
        Person(){}
    
    
        string name;
    
    
        Person(string name){
            this->name = name;
        }
    
    
        bool operator>(Person& p){
            return name.compare(p.name) > 0;
        }
    };
    
    
    template<class T>
    class Personenverwaltung{
    
    
    public:
    
    
        T arr[3];
    
    
        bool isSorted(){
    
    
            for(int i = 0; i < 2; i++){
                if(arr[i] > arr[i+1]){
                    return false;
                }
            }
    
    
            return true;
        }
    
    
        int compare(T t, int i){
    
    
            if(arr[i] > t)    return 1;
    
    
            return 0;
        }
    
    
        T get(int i){
    
    
            return arr[i];
        }
    
    };
    
    
    
    
    int main(){
    
    
    
    
        Person p_0("Mueller"); Person p_1("Schreiner");    Person p_2("Gehrer");
        Person p("Faerber");
    
        Personenverwaltung<Person> pv;
    
    
        pv.arr[0] = p_0;
        pv.arr[1] = p_1;
        pv.arr[2] = p_2;
    
    
        cout << pv.isSorted() << endl;
    
    
        cout << pv.compare(p,1) << endl;
    
        cout << pv.get(2).name << endl;
    
    
        return 0;
    }
    Alles anzeigen

    "Von der Gewalt, die alle Wesen bindet, befreit der Mensch sich, der sich überwindet." > Learn more ...

  • gelbasack
    25
    gelbasack
    Mitglied
    Reaktionen
    90
    Punkte
    6.525
    Beiträge
    1.241
    • 29. August 2007 um 15:55
    • #2

    Wenn's in einem File funktioniert, klingt das auf den ersten Blick nach folgendem Problem:
    Der C++ Compiler übersetzt die Templates statisch, das heißt beim Kompilieren wird geschaut mit welchen Typen du die Templateklasse verwendest und für jeden Typ wird eigener Code übersetzt. Wenn du den Templatecode jetzt aufteilst und als eigenes Object File kompilieren möchtest, weiß der Compiler nicht, welche Typen hier eingesetzt gehören und kann für keine Code erzeugen.
    Den ganzen Templatecode musst du deswegen in einem Headerfile lassen. Erst beim Übersetzen ins eigentliche Programm, wird der Code dann kompiliert für die entsprechenden Typen.
    Hoffe, das war halbwegs richtig erklärt und ist der Fehler, klingt aber irgendwie danach... und wenn nicht, findet sich eh sicher jemand, der mich steinigt :)

  • sauzachn
    17
    sauzachn
    Mitglied
    Reaktionen
    51
    Punkte
    3.101
    Beiträge
    606
    • 29. August 2007 um 16:01
    • #3

    Wird ein generischer Typ nicht inline verwendet, sondern außerhalb der Klassendefinition verwendet, muss man immer template<typename T> (analog zur Klassendeklaration) voranstellen. Die Klasse selbst muss incl. Templateparameter angegeben werden, ein Beispiel:

    Code
    template <typename T>
    struct Stack {
     T& pop();
    };
    
    
    template <typename T>
    T& Stack<T>::pop() { ....}

    Dipper dipper dii dipper dii dipper dii duuu

  • Blixa Barscheck
    12
    Blixa Barscheck
    Mitglied
    Reaktionen
    11
    Punkte
    1.406
    Beiträge
    229
    • 29. August 2007 um 17:25
    • #4
    Code
    template<class T> bool Personenverwaltung<T>::isSorted(){
    
    
        for(int i = 0; i < 2; i++){
            if(arr[i] > arr[i+1]){
                return false;
            }
        }
    
    
        return true;
    }
    
    
    template<class T> int Personenverwaltung<T>::compare(T t, int i){
    
    
        if(arr[i] > t)    return 1;
    
    
        return 0;
    }
    
    
    template<class T> T Personenverwaltung<T>::get(int i){
    
    
        return arr[i];
    }
    Alles anzeigen

    ok, danke einmal!
    Auf die Art kompiliert dann auch 'Personenverwaltung.cpp'.

    Allerdings erhalte ich folgende Fehler beim Linken:

    Code
    main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: class Person __thiscall Personenverwaltung<class Person>::get(int)" (?get@?$Personenverwaltung@VPerson@@@@QAE?AVPerson@@H@Z)" in Funktion "_main".
    main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: int __thiscall Personenverwaltung<class Person>::compare(class Person,int)" (?compare@?$Personenverwaltung@VPerson@@@@QAEHVPerson@@H@Z)" in Funktion "_main".
    main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: bool __thiscall Personenverwaltung<class Person>::isSorted(void)" (?isSorted@?$Personenverwaltung@VPerson@@@@QAE_NXZ)" in Funktion "_main".
    Template2.exe : fatal error LNK1120: 3 nicht aufgelöste externe Verweise.

    Lösch ich nur die drei 'cout'-Anweisungen mit den
    Methodenzugriffen, so funktioniert alles einwandfrei

    "Von der Gewalt, die alle Wesen bindet, befreit der Mensch sich, der sich überwindet." > Learn more ...

  • fren
    4
    fren
    Mitglied
    Punkte
    160
    Beiträge
    32
    • 29. August 2007 um 20:54
    • #5

    Personenverwaltung.cpp müsste eigentlich leer sein. Du musst die Definitionen der methoden ebenso ins .h file ziehen. Den Grund hat gelbasack schon erklärt. Ich nehme mal an du stehst jetzt vor diesem Problem (wirkt sich immer nur auf linken aus).

    Theoretisch gäbe es noch 2 möglichkeiten das ganze im .cpp zu lassen:
    a) explizite instanzierung:

    du fügst im Personenverwaltung.cpp noch folgendes ein (Person muss natürlich bekannt sein ...):

    template class Personenverwaltung<Person>;

    b) das keyword export

    dies ist im c++-standard enthalten und "löst" genau dieses problem - es ist aber das einzige c++-feature, dass kein gängiger compiler unterstützt (aus gutem grund) - daher forget it :)

  • Maximilian Rupp 27. Dezember 2024 um 12:05

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 1 Besucher

Rechtliches

Impressum

Datenschutzerklärung