[c++] Template-Funktionen einer Klasse hinzufügen - wie richtig?

radazong

Mitglied
Hello again!

Ich habe folgendes Problem:
Ich habe mir eine Klasse geschrieben, die Template-Funktionen enthält - sprich, es wird nicht festgelegt welche Typen übergeben werden müssen, um die Klasse flexibel zu gestalten ;).

Allerdings erhalte ich bei Aufruf dieser Funktionen im Programm eine Fehlermeldung:
Code:
  [Linker error] undefined reference to `bool DATABASE::addentry<Entry>(Entry*, char*)'

Betroffen sind dabei wirklich nur die Template-Funktionen, da vorher aufgerufene Memberfunktionen nicht bemängelt werden. Habe die Funktionen wie folgt deklariert:

C++:
 template<class T>bool search(T* object, char*search);
 template<class T>bool addentry(T* object,char*name);

und später so definiert:

C++:
template<class T>bool DATABASE::search(T* object, char*search)
      {
//................
      }
      
      
      template<class T>bool DATABASE::addentry(T* object,char*name)
      {
//.................
       }

Ich habe bisher nicht wirklich mit Templates gearbeitet, daher denke ich mal ich habe irgendwas in der Definition vermurkst - vielleicht kann mich ja jemand in der Hinsicht aufklären.
Bin für jeden Tipp dankbar,

Gruß
 
Hallo!

Jetzt ist es eine Template-Klasse .... muss denn die ganze Klasse eine template-klasse sein, wenn ich doch nur 2 Funktionen habe, die das nutzen.

Mit instanzieren meinst du sicherlich bennenen?....
C++:
int main()
{
//...

DATABASE<Entry> Data;

//....
}

Musste irgendwie nun sämtliche Memberfunktionen in Form von:
C++:
template<class T> *Rückgabetyp* *Klassenname*<T>::*Funktionsname*( )

definieren. Oder hab ich da bei dem Beispiel, dass ich eben aus dem Netz gefischt habe, etwas falsch verstanden?
Jetzt bekomme ich übrigens wenn ich das Programm kompilieren möchte folgende Fehlermeldung:
Code:
6 F:\programmieren\Projekte\Datenverarbeitung\database.h `DATABASE' is not a template

Habe den Klassenkopf nun folgendermaßen geschrieben:
C++:
template<class T>DATABASE
{
/*.....*/
}

Hmpf, hab mir das mit meinen ollen Templates wohl ein wenig zu einfach vorgestellt :D
Vielen Dank auf jeden Fall bis jetzt schonmal.... schade das VHS-Programmierkurse so teuer sind - ist manchmal echt nicht leicht alles auf eigene Faust durch learning by doing zu verstehen.

Gruß
 
Hi.
Hallo!

Jetzt ist es eine Template-Klasse .... muss denn die ganze Klasse eine template-klasse sein, wenn ich doch nur 2 Funktionen habe, die das nutzen.
Nein, die Klasse muss es nicht sein. Aber es macht normalerweise nicht viel Sinn Methoden per Template für eine Klasse zu generieren.

Aber was willst du mit den Methoden überhaupt erreichen? Wenn du sowieso nur Zeiger speicherst, könntest du den Typ gleich auf "void*" festlegen.

Mit instanzieren meinst du sicherlich bennenen?....
Mit Instanzieren meine ich explizit bzw. implizit instanzieren. ;)

Du mußt die Definition der Template Funktionen mit in die Headerdatei schreiben oder zumindest so, das sie wenn sie gebraucht werden auch instanziert werden können.

C++:
class A {

public: 
  
  template <typename T> void test(T);
};

template <typename T>
void A::test(T arg) {
  cout << arg;
}

A a;

a.test(5);
 
Naja, in der Funktion sollen Dateioperationen mit zb. fread() bzw fwrite() ausgeführt werden. Irgendwie bekomm ich das mit einem void-Zeiger nicht zum laufen.
Die letzte Fehlermeldung war:

Code:
partial specialization `search<T*>' of function template

Ich denke ich sollte mich tiefergehend mit Templates befassen. Vielleicht magst du mir ja eine "richtige" Implementation zeigen? Ansonsten schonmal-wie schon so oft- vielen dank :).

Gruß
 
Naja, in der Funktion sollen Dateioperationen mit zb. fread() bzw fwrite() ausgeführt werden. Irgendwie bekomm ich das mit einem void-Zeiger nicht zum laufen.
Die letzte Fehlermeldung war:

Code:
partial specialization `search<T*>' of function template

Ich denke ich sollte mich tiefergehend mit Templates befassen. Vielleicht magst du mir ja eine "richtige" Implementation zeigen?
Also wenn du nur die Größe des Typs für fwrite/fread automatisch per Template erzeugen zu lassen, war ja dein erster Ansatz schon gut.
C++:
class A {

public: 
  
  template <typename T> void test(T*);
};

template <typename T>
void A::test(T* arg) {
  fwrite(arg, sizeof(*arg), 1, file);
}

A a;

a.test(&a);
Gruß

PS: Die Objekte werden allerdings auch nur als oberflächliche Kopie gespeichert. Wenn es sich um komplexe Objekte handelt kannst du diese nicht mehr aus der Datei wieder herstellen.
 
Hallo.

Irgendwie sind Templates n doofes Thema ^^ . Ich habe versucht es so zu schreiben wie in deinem Beispiel, allerdings kam dann beim kompilieren :

Code:
undefined Reference to template<typename T> void DATABASE::search(/*...*/)

Das Problem lies sich beheben, indem ich die Definition der Funktionen in den Header gepackt habe. Darum nun auch meine erste Frage:

- Warum muss ich die Funktionsdefiniton mit in die HeaderDatei packen, und nicht wie sämtliche andere Definitionen in die zugehörige .cpp ? und die zweite Frage :

- Besteht ein Unterschied zwischen template<class T>/*...*/
und template<typename T>/*...*/ - und wenn ja, welcher ist das?

Naja, das Prog lies sich zwar kompilieren, schmiert aber dann ab. Muss wahrschl meine Implementation nochmal überdenken, die Templates jedoch scheinen nun zu funktionieren.

Gruß
 
Hi.
Irgendwie sind Templates n doofes Thema ^^ . Ich habe versucht es so zu schreiben wie in deinem Beispiel, allerdings kam dann beim kompilieren :

Code:
undefined Reference to template<typename T> void DATABASE::search(/*...*/)

Das Problem lies sich beheben, indem ich die Definition der Funktionen in den Header gepackt habe.
Was ich dir aber bereits gesagt hatte...
Darum nun auch meine erste Frage:

- Warum muss ich die Funktionsdefiniton mit in die HeaderDatei packen, und nicht wie sämtliche andere Definitionen in die zugehörige .cpp ?
Templates sind Schablonen die der Kompiler verwenden kann um konkrete Instanzen des Templates zu bilden. Die Schablone muss beim Kompilieren verfügbar sein, sonst kann logischerweise keine Instanz erzeugt werden.
und die zweite Frage :

- Besteht ein Unterschied zwischen template<class T>/*...*/
und template<typename T>/*...*/ - und wenn ja, welcher ist das?
Nein, semantisch gibt es keinen Unterschied. Allerdings sagt das Wort "class" eher aus, dass dort nur eine Klasse für den Templateparameter T eingesetzt werden kann, was nicht ganz richtig ist, denn normalerweise kann dort ein beliebiger Typ eingesetzt werden. Der Templateparameter steht also eigentlich nicht für eine "Klasse" sondern für einen "Typnamen".

Gruß
 
Zurück