tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
NEIN
ANTWORTEN
16
ZUGRIFFE
4236
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    zarilla zarilla ist offline Mitglied Silber
    Registriert seit
    Jan 2004
    Beiträge
    54
    Irgendwo hab ich mal gelesen das Methoden die direkt in der Klassendefinition definiert werden automatisch inline sind.
    Trifft das bei Templates auch zu ?
     

  2. #2
    Thomas Kuse Thomas Kuse ist offline Mitglied Rubin
    Registriert seit
    Aug 2001
    Beiträge
    1.411
    Im Fall vom Visual C++ Compiler bin ich mir so ziemlich sicher, dass das auch bei Templates so ist.
    Ein übersichtliches Programmieren erfordert an Sich schon ein separates Header-File, dann kann man die Methoden inline machen, die dafür geschaffen sind.
    Die Sache ist aber, dass sowas wirklich vom Compiler und auch von gesetzten Compiler-Flags, wie man es beim gcc bzw g++ macht, abhängt
     

  3. #3
    zarilla zarilla ist offline Mitglied Silber
    Registriert seit
    Jan 2004
    Beiträge
    54
    Und Templateklassen können auch genau wie "normale" Klasse deklariert werdern ?
    dh Klasse in .h und Methodendefinition in .cpp ?
     

  4. #4
    chibisuke chibisuke ist offline Mitglied Brillant
    Registriert seit
    Sep 2003
    Beiträge
    807
    Natürlich, wie willst du sie sonst deklarieren?

    Bedenke nur, das man von Template klassen keine library oder DLL anlegen kann, ohne die klassen explizit für alle datentypen zu instanzieren für die man sie benutzen will.

    grundsätzlich sieht das so aus:

    headerdatei:
    Code :
    1
    2
    3
    4
    5
    6
    
     
    template <class T> class MyTemplateClass : public AnotherClass {
       public:
          T* getObject();
          //...
    };
    cpp datei:
    Code :
    1
    2
    3
    
    template<class T> T* MyTemplateClass::getObject() {
       return new T();
    }

    Das sich diese klasse hier absolut nix bringt, is klar, aber das soll ja nur n beispiel sein
     

  5. #5
    Tobiasm Tobiasm ist offline Mitglied Silber
    Registriert seit
    Apr 2003
    Ort
    Lemgo (NRW)
    Beiträge
    83
    Bist Du sicher, dass Templates in eine Cpp-Datei gehören? AFAIK gehören sie entweder direkt in den Header oder aber in eine Datei, die in den Header per #include "..." eingebunden wird.

    Der Grund ist folgender: "When writing template classes, function definitions are usually stored in a header file along with their declarations, and not in a separate .cpp file. Trying to do otherwise typically will result in a linker error. This is because most compilers require template definitions to be available to each translation unit that uses them, through the inclusion of header files." (http://www.codeguru.com/atl/KD062002.html - Stand 22.01.04)

    Ich weiß jetzt aber nicht, ob es schon weit verbreitete Compiler bzw. Linker (z.B. GCC) gibt, die das nicht mehr brauchen.

    MfG

    Tobias
     

  6. #6
    zarilla zarilla ist offline Mitglied Silber
    Registriert seit
    Jan 2004
    Beiträge
    54
    also ich habe es in Dev-C++ (GCC) folgendermaßen probiert:
    MyTemplateClass.h:
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    template <class T> class MyTemplateClass {
       public:
          MyTemplateClass(void);
          T* getObject();
          int size(void);
          //...
    };
    myTemplateClass.cpp:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    #include "MyTemplateClass.h"
     
    template<class T> T* MyTemplateClass::getObject() {
       return new T();
    }
    template<class T> MyTemplateClass::MyTemplateClass(void)
    {
        cout<<"HELLO"<<endl;
    }
    template<class T> int MyTemplateClass::size(void)
    {
        cout<<"Grösse: "<<sizeof(T)<<endl;
        return 0;
    }
    main.cpp:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    #include <iostream>
    #include <stdlib.h>
    #include "MyTemplateClass.h"
    using namespace std;
     
    int main(void)
    {
      MyTemplateClass<int> ttest();
      ttest.size(); 
      system("Pause");
      return 0; 
    }

    und es funktioniert irgendwie nicht...
    16 main.cpp request for member `size' in `ttest()', which is of non-aggregate
    Das Template std::Vector ist auch in der header-datei definiert.
    Aber ich zweifle irgendwie daran das alle Templatemethoden inline sein sollen !?
    Geändert von zarilla (22.01.04 um 21:36 Uhr)
     

  7. #7
    Tobiasm Tobiasm ist offline Mitglied Silber
    Registriert seit
    Apr 2003
    Ort
    Lemgo (NRW)
    Beiträge
    83
    Siehe mein Beitrag direkt über Deinem.

    MfG

    Tobias
     

  8. #8
    zarilla zarilla ist offline Mitglied Silber
    Registriert seit
    Jan 2004
    Beiträge
    54
    ja ok
    aber wie dann ?
    selbst das deklarieren im selben header funktioniert nicht.
     

  9. #9
    chibisuke chibisuke ist offline Mitglied Brillant
    Registriert seit
    Sep 2003
    Beiträge
    807
    Original geschrieben von Tobiasm
    Bist Du sicher, dass Templates in eine Cpp-Datei gehören? AFAIK gehören sie entweder direkt in den Header oder aber in eine Datei, die in den Header per #include "..." eingebunden wird.

    Der Grund ist folgender: "When writing template classes, function definitions are usually stored in a header file along with their declarations, and not in a separate .cpp file. Trying to do otherwise typically will result in a linker error. This is because most compilers require template definitions to be available to each translation unit that uses them, through the inclusion of header files." (http://www.codeguru.com/atl/KD062002.html - Stand 22.01.04)

    Ich weiß jetzt aber nicht, ob es schon weit verbreitete Compiler bzw. Linker (z.B. GCC) gibt, die das nicht mehr brauchen.

    MfG

    Tobias
    Also ich hab selbst schon Template klassen geschrieben und die funktionen in cpp dateien gepackt, funktioniert anstandslos...
    Ich benutze VC++ 6.0 als Compiler.

    Linkerfehler hatte ich erst als ich versucht hab die Template klasse in eine LIB zu packen, denn dann musste ich zuerst die klasse in der lib explizit instanzieren für jeden zu verwendenden datentyp.
     

  10. #10
    Tobiasm Tobiasm ist offline Mitglied Silber
    Registriert seit
    Apr 2003
    Ort
    Lemgo (NRW)
    Beiträge
    83
    @chibisuke: Also, ich habe mit meinem VC++.NET ausprobiert die Definition der Funktionen in eine cpp-Datei auszulagern und nur die Definition der Klasse im Header zu lassen. Daraufhin habe ich die Fehlermeldung von dem Linker erhalten, dass die Funktionen, die ich ausgelagert hatte, nicht aufgelöst werden konnten. Außerdem kann ich mir schwer vorstellen, dass sich der VC++ 6 Compiler da wesentlich anders verhält. Hast Du vielleicht die CPP-Datei vielleicht in die Header-Datei eingebunden oder hast Du explizite Template-Instanzierung genutzt ?

    @zarilla: Hast Du mal

    Code :
    1
    
     template<class T> T* MyTemplateClass<T>::getObject()

    probiert. Vermutlich fehlt nur das <T> hinter MyTemplateClass.

    MfG

    Tobias
     

  11. #11
    chibisuke chibisuke ist offline Mitglied Brillant
    Registriert seit
    Sep 2003
    Beiträge
    807
    Anfangs weder noch, die Explizite Typeninstanzierung war erst erforderlich als ich eine lib draus erzeugt hab...

    wie auch immer, ich halte nix davon methoden in H dateien zu schreiben, gibts nämlich gern ärger mit dem linker, weil er dann wenn man die mehrmals verwendet oft doppelt existieren und der linker dann nie weiß welche er benutzen soll.

    Naja Egal, solange es funktioniert passt es.
     

  12. #12
    Tobiasm Tobiasm ist offline Mitglied Silber
    Registriert seit
    Apr 2003
    Ort
    Lemgo (NRW)
    Beiträge
    83
    Kannst Du mal den Code posten (wenn er jetzt nicht geheim bzw. vertraglich geschützt ist) ? Jetzt interessiert es mich wirklich mal, wie Du das gemacht hast.

    MfG

    Tobias
     

  13. #13
    zarilla zarilla ist offline Mitglied Silber
    Registriert seit
    Jan 2004
    Beiträge
    54
    hab ich das richtig verstanden das chibisuke template-methoden in cpp dateien definiert hat ?
    dann darf diese cpp aber nicht mit kompiliert werden oder ?
     

  14. #14
    Tobiasm Tobiasm ist offline Mitglied Silber
    Registriert seit
    Apr 2003
    Ort
    Lemgo (NRW)
    Beiträge
    83
    Nein, eigentlich nicht, den Grund hatte ich ja schon weiter oben geschrieben. Deshalb habe ich ja auch extra nach dem Quellcode gefragt, weil mich interessiert, wie er das gemacht hat.
     

  15. #15
    chibisuke chibisuke ist offline Mitglied Brillant
    Registriert seit
    Sep 2003
    Beiträge
    807
    Also ich würde dir ja das gesamte projekt als source geben, damit du es selbst kompilieren kannst, aber 1.) is das projekt mittlerweile 40MB reiner source, und 2.) sind große teile des codes aus sicherheitsgründen unter verschluss.(cryptographierechniken, übertragungsprotokolle, ..)

    Die klasse von der ich rede is so simple,dass ich sie dir zeichen kann.

    aus corelib.lib:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    
    // -------------------------------------------------
    // CHashtable.cpp
    // -------------------------------------------------
    // (c) 2003, BeamVision
    // Alle Rechte vorbehalten 
    // -------------------------------------------------
     
    #include "../common/CHashtable.h"
     
    ///////////////////////////////////////////////////////////////
    // TEMPLATE T: class to use as a class for the Hashtable
    ///////////////////////////////////////////////////////////////
     
    ///////////////////////////////////////////////////////////////
    // constructs the element
    //
    template <class T> CHashtable<T>::CHashtable() {
        this->data = new CArray();
    }
       
    ///////////////////////////////////////////////////////////////
    // every element entered in the hashtable is deleted
    //    when it is removed
    //
    template <class T> CHashtable<T>::~CHashtable() {
        for(unsigned int i = 0; i < this->data->countItems(); i++) {
            if(this->data->GetItem(i) != NULL) {
                delete this->data->GetItem(i);
            }
        }
        delete this->data;
    }
     
    /////////////////////////////////////////////////////////////
    // retrived a entry of the hashtable
    // @param: the name of the assiciated object
    // @return: Template type entry associated with the name
    //
    template <class T> T* CHashtable<T>::get(char* name) {
        CHashtableEntry<T> *tmp1;
        for(unsigned int i = 0; i < this->data->countItems(); i++) {
            if(this->data->GetItem(i) != NULL) {
                tmp1 = (CHashtableEntry<T>*)this->data->GetItem(i);
                if(_stricmp(tmp1->name, name) == NULL) {
                    return (T*)((CHashtableEntry*)this->data->GetItem(i))->object;
                }
            }
        }
        return NULL; 
    }
     
    /////////////////////////////////////////////////////////////
    // adds a new element to the Hashtable
    // @param: name of the object, is duplicated afterwards
    // @param: pointer to the object to insert, should be
    //         allocated on the heap
    //
    template <class T> void CHashtable<T>::insert(char* name, T* obj) {
        this->data->AddItem(new CHashtableEntry<T>(obj, strdup(name))); 
    }
     
    /////////////////////////////////////////////////////////////
    // removes and deletes a specified item from the 
    //           hashtable
    // @param: name of the element
    //
    template <class T> void CHashtable<T>::remove(char* name) {
        for(unsigned int i = 0; i < this->data->countItems(); i++) {
            if(this->data->GetItem(i) != NULL) {
                if(_stricmp(((CHashtableEntry*)this->data->GetItem(i))->name, name) == NULL) {
                    delete ((CHashtableEntry*)this->data->GetItem(i));
                    this->data->DeleteItem(i);
                }
            }
        }
    }
     
    ////////////////////////////////////////////////////////////////
    // contructs a new Hashtable entry, should not be
    //        used by any other element then CHashtable and childs
    // @param: object to insert
    // @param: name to be duplicated and inserted
    //
    template <class T> CHashtableEntry<T>::CHashtableEntry(T* obj, char* name) {
        this->object = obj;
        this->name = _strdup(name);
    }
     
    ////////////////////////////////////////////////////////////////
    // this ctor is only for use in exceptional cases
    //        it should not be used regularly
    // 
    template <class T> CHashtableEntry<T>::CHashtableEntry() {
        this->name = NULL;
        this->object = NULL;
    }
     
    ////////////////////////////////////////////////////////////////
    // destructs the element, and deletes any associated values
    template <class T> CHashtableEntry<T>::~CHashtableEntry() {
        if(this->name) {
            delete this->name;
        }
        if(this->object) {
            delete this->object;
        }
    }
     
    /////////////////////////////////////////////////////////////////
    // Create Virtual instance of CHashtable
    //       this must be done 'cause we are working inside
    //       a library.
     
    template class CHashtable<char>;
    template class CHashtable<_CObject>;
    template class CHashtableEntry<char>;
    template class CHashtableEntry<_CObject>;

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    #pragma once
    // -------------------------------------------------
    // CHashtable.h
    // -------------------------------------------------
    // (c) 2003, BeamVision
    // Alle Rechte vorbehalten
    // -------------------------------------------------
     
    //TEMPLATE-CLASS
     
    #include "CArray.h"
    #include <string.h>
    #ifndef NULL
    #   define NULL 0
    #endif
     
    template <class T> class CHashtable :public _CObject {
        public:
            CHashtable();
            ~CHashtable();
     
            T* get(char* name);
            void insert(char* name, T* obj);
            void remove(char* name);
     
        protected:
            CArray* data;
    };
     
    template <class T> class CHashtableEntry :public ::_CObject {
        public:
            CHashtableEntry();
            CHashtableEntry(T*, char*);
            ~CHashtableEntry();
     
            T* object;
            char* name;
    };

    Während ich die klasse geschrieben und getestat hab hatte sie noch keine explizite instanzierung, und war in der haupt DLL enthalten. Nachdem die Tests abgeschlossen waren, kam sie in éine lib, was die explizite instanzierung erforderlich machte.seither wurde nichts mehr verändert.

    Verwendung natürlich wie auch sonst üblich, header einbinden, CPP datei einfügen ins projekt, und los gehts...
    eventuell ein typedef...wenn man zu faul ist jedesmal diese <T> anzugeben...

    Der code stammt aus meinem aktuellen projekt Chimera-Crystals.
    Geändert von chibisuke (25.01.04 um 01:18 Uhr)
     

Ähnliche Themen

  1. Template und Inline Funktionsdefinitionen
    Von lemon03 im Forum C/C++
    Antworten: 2
    Letzter Beitrag: 25.05.10, 08:16
  2. Wir sind auch noch da!
    Von Lila22 im Forum Fotografie
    Antworten: 2
    Letzter Beitrag: 11.10.07, 08:16
  3. Antworten: 2
    Letzter Beitrag: 27.06.07, 01:07
  4. get und set Methoden automatisch erstellen
    Von Panda Cabrio im Forum VisualStudio & MFC
    Antworten: 0
    Letzter Beitrag: 28.03.06, 14:12
  5. Antworten: 3
    Letzter Beitrag: 25.11.04, 13:58