ERLEDIGT
NEIN
NEIN
ANTWORTEN
16
16
ZUGRIFFE
4236
4236
EMPFEHLEN
-
Irgendwo hab ich mal gelesen das Methoden die direkt in der Klassendefinition definiert werden automatisch inline sind.
Trifft das bei Templates auch zu ?
-
21.01.04 19:44 #2
- 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
-
Und Templateklassen können auch genau wie "normale" Klasse deklariert werdern ?
dh Klasse in .h und Methodendefinition in .cpp ?
-
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:
cpp datei:Code :1 2 3 4 5 6
template <class T> class MyTemplateClass : public AnotherClass { public: T* getObject(); //... };
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
-
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 habe es in Dev-C++ (GCC) folgendermaßen probiert:
MyTemplateClass.h:
myTemplateClass.cpp:Code :1 2 3 4 5 6 7
template <class T> class MyTemplateClass { public: MyTemplateClass(void); T* getObject(); int size(void); //... };
main.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; }
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)
-
Siehe mein Beitrag direkt über Deinem.
MfG
Tobias
-
ja ok
aber wie dann ?
selbst das deklarieren im selben header funktioniert nicht.
-
Also ich hab selbst schon Template klassen geschrieben und die funktionen in cpp dateien gepackt, funktioniert anstandslos...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
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.
-
@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
-
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.
-
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
-
hab ich das richtig verstanden das chibisuke template-methoden in cpp dateien definiert hat ?
dann darf diese cpp aber nicht mit kompiliert werden oder ?
-
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.
-
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
-
Template und Inline Funktionsdefinitionen
Von lemon03 im Forum C/C++Antworten: 2Letzter Beitrag: 25.05.10, 08:16 -
Wir sind auch noch da!
Von Lila22 im Forum FotografieAntworten: 2Letzter Beitrag: 11.10.07, 08:16 -
[c++][template][operatoren] linker findet Methoden nicht
Von eclarion im Forum C/C++Antworten: 2Letzter Beitrag: 27.06.07, 01:07 -
get und set Methoden automatisch erstellen
Von Panda Cabrio im Forum VisualStudio & MFCAntworten: 0Letzter Beitrag: 28.03.06, 14:12 -
Kann man auch PHP-Dateien als Template-Funktion nutzen
Von pamali im Forum PHPAntworten: 3Letzter Beitrag: 25.11.04, 13:58





Zitieren
Login






