templates und pointer



  • hallo leute,

    ich habe eine klasse für eine liste erstellt. die soll verschiedenartige nodes aufnehmen können (alle von einer hauptnode abgeleitet). dazu habe ich templates benutzt.

    wenn ich nun einen pointer auf solch eine liste setze und mit new speicherplatz anfordere kommt immer ein compiler fehler. irgendwie bin ich mit meinem latain dort am ende. vielleicht habt ihr eine lösung für dies problem.

    hier mal der quelltext:
    an folgender stelle meldet gcc und windows immer "undefined reference to 'List::<Buchungen>::List()'"

    int main()
    {
        List<Buchungen>* ll = new List<Buchungen>();
        return 0;
    }
    

    meine listen klasse:

    #ifndef LIST_H_
    #define LIST_H_
    
    #include "Node.h"
    
    template <class NodeType> class List
    {
    private:
    	NodeType *first;
    	NodeType *last;
    	int count;
    
    public:
    	List(void);
    	~List(void);
    
    	int getCount(void);
    
    	NodeType * getFirstNode(void);
    	NodeType * getLastNode(void);
    
    	void addNodeBack(NodeType * n);
    	void addNodeFront(NodeType * n);
    
    	void deleteFirstNode();
    
    	void insertAfter(NodeType * n, NodeType * ne);
    
    	void sortInsertion(int (NodeType::*comparator)(NodeType *));
    };
    
    #endif /*LIST_H_*/
    

    die node

    #ifndef NODE_H_
    #define NODE_H_
    
    class Node
    {
    	//friend class List;
    
    protected:
    	Node* next;
    	void setNext(Node* n);
    
    public:
    	Node(void);
    	~Node(void);
    
    	Node* getNext();
    
    	int comparator(Node *);
    };
    
    #endif /*NODE_H_*/
    

    und die abgeleitete klasse buchungen

    #ifndef BUCHUNGEN_H_
    #define BUCHUNGEN_H_
    
    #include "Node.h"
    #include <string>
    using namespace std;
    
    class Buchungen : public Node {
    private:
    	double Betrag;
    	int Menge;
    	string* BuchText;
    	string* KontoText;
    
    public:
    	Buchungen(void);
    	~Buchungen(void);
    
    	void setBetrag(double b);
    	void setMenge(int m);
    	void setBuchText(string* bt);
    	void setKontoText(string* kt);
    
    	double getBetrag(void);
    	int getMenge(void);
    	string* getBuchText(void);
    	string* getKontoText(void);
    
    	int compareToBetrag(Buchungen* c);
    	int compareToMenge(Buchungen* c);
    	int compareToBuchText(Buchungen* c);
    	int compareToKontoText(Buchungen* c);
    };
    #endif /*BUCHUNGEN_H_*/
    

    vielen dank,
    sjoe



  • Die Klasse 'List' ist eine Template-Klasse, da mußt du die Implemntierung der Methoden direkt vor Ort vornehmen, damit der Compiler sie wiederfindet (wenn du das in eine eigene .CPP auslagerst, weiß der Compiler nicht, was für List<> Spezialisierungen benötigt werden).

    Übrigens: Wenn du mit Templates arbeitest, mußt du nicht auf einer vorgegebenen Vererbungshierarchie arbeiten 😉 Du solltest lieber die Node-Klasse auch als Template definieren und deine Datenklasse (Buchungen oder ähnliches) dort reinkapseln:

    template<typename T>
    class Node
    {
      T data;
      Node* next;
      ...
    };
    
    template<typename T>
    class List
    {
      Node<T>* first;
      Node<T>* next;
      ...
    };
    


  • vielen dank für die antwort,
    auf sowas kommt man ja nie.

    mfg sjoe



  • eine kleine nachfrage zu den templates.
    wie kann ich die templatisierte klasse list in node als friend setzen?

    "friend class List<T>;" geht leider nicht.

    geht das überhaupt nicht oder gibt es dafür irgendwelche kniffe?

    mfg sjoe





  • Da benötigst du afaik eine Forward-Deklaration, damit der Compiler das Template richtig zuordnen kann:

    template<typename T> class List;
    
    template<typename T>
    class Node
    {
      friend class List<T>;
      ...
    };
    
    template<typename T>
    class List
    {
      ...
    };
    

    evt. ist es für die Datenkapselung sogar günstiger, die Node-Klasse in der List zu definieren:

    template<typename T>
    class List
    {
    private:
      struct Node
      {
        ...
      };
      ...
    };
    

    PS: Wenn du dir Arbeit sparen willst, kannst du auch std::list verwenden 😉 Das ist fertig und kann auch recht flexibel eingesetzt werden.


Anmelden zum Antworten