Antons1 Skrevet 23. april 2012 Del Skrevet 23. april 2012 Hei! Sitter og jobber med en oppgave i C++, og støter på et, for meg, merkelig problem: Det er stort sett en del av oppgavene at vi skal deklarere alt av klasser og funksjoner i egne header-filer/cpp-filer, og dette går som regel fint helt til vi begynte med templates. Når jeg nå skal kompilere et program med en templateklasse for en lenket liste, får jeg opp LNK2019-feil ved kompilering. Dersom jeg putter alt av deklarasjoner og implementasjoner i main.cpp er det ikke noe problem, og programmet fungerer som det skal. Er det noe jeg kan gjøre for at dette skal fungere? Jeg bruker Visual C++ Express 2010 på Windows 7 x64. Her er filene og feilene: main.cpp #include <iostream> #include <string> #include "Oving10template.h" using namespace std; int main(){ LinkedList<string> navneListe = LinkedList<string>(); navneListe.insertAtBack("Sigrid"); navneListe.insertAtBack("Ruben"); navneListe.insertAtBack("Rune"); navneListe.insertAtBack("Knut"); navneListe.insertAtBack("Bjørnar"); navneListe.insertAtBack("Signe"); navneListe.insertAtBack("Hakon"); navneListe.insertAtBack("Erlend"); navneListe.insertAtBack("Marianne"); navneListe.insertAtBack("Kristin"); cout << navneListe; system("PAUSE"); return 0; } oving10template.h #ifndef OVING_10_TEMPLATE_ #define OVING_10_TEMPLATE_ #include <string> using namespace std; template<class T> class ListNode{ private: T value; ListNode<T> *next; public: ListNode(const T &); T getValue() const; ListNode<T> *getNext() const; template<class U> friend class LinkedList; }; template<class T> class LinkedList{ private: ListNode<T> *head; ListNode<T> *last; public: LinkedList(); ~LinkedList(); bool isEmpty(); void insertAtFront(const T &); void insertAtBack(const T &); bool removeFromFront(/*T&*/); bool removeFromBack(/*T&*/); ListNode<T> * search(const T &); void remove(const T &); template<typename U> friend ostream &operator <<(ostream &, const LinkedList<U> &); }; #endif oving10template.cpp #include <string> #include <iostream> #include "Oving10Template.h" using namespace std; //Implementasjon ListNode template<typename T> ListNode<T>::ListNode(const T &value){ this->value = value; this->next = NULL; } template<typename T> T ListNode<T>::getValue() const{ return this->value; } template<typename T> ListNode<T>* ListNode<T>::getNext() const{ return this->next; } template<typename T> LinkedList<T>::LinkedList(){ this->head = NULL; this->last = NULL; } template<typename T> LinkedList<T>::~LinkedList(){ if(!isEmpty()){ do{ ListNode<T> *delNext = (*head).getNext(); delete(head); head = delNext; } while(head != NULL); } } template<typename T> bool LinkedList<T>::isEmpty(){ return (this->head == NULL && this->last == NULL); } template<typename T> void LinkedList<T>::insertAtFront(const T &value){ ListNode<T> *atFront = new ListNode<T>(value); if(isEmpty()){ this->head = atFront; this->last = atFront; } else { (*atFront).next = this->head; this->head = atFront; } } template<typename T> void LinkedList<T>::insertAtBack(const T &value){ ListNode<T> *atBack = new ListNode<T>(value); if(isEmpty()){ this->head = atBack; this->last = atBack; } else { (*this->last).next = atBack; last = atBack; } } template<typename T> bool LinkedList<T>::removeFromFront(/*T &value*/){ if(isEmpty()) return false; ListNode<T> *temp = (*this->head).getNext(); delete(this->head); this->head = temp; return true; } template<typename T> bool LinkedList<T>::removeFromBack(/*T &value*/){ if(isEmpty()) return false; if(this->head == this->last){ delete(this->head); } else { ListNode<T> *previous = this->head; ListNode<T> *current = (*this->head).getNext(); while(current != this->last){ previous = current; current = (*previous).getNext(); } delete(this->last); this->last = previous; (*this->last).next = NULL; } return true; } template<typename U> ostream& operator <<(ostream& os, const LinkedList<U>& li){ ListNode<U> *current = li.head; if(current != NULL){ do{ os << (*current).getValue() << endl; current = (*current).getNext(); }while(current != NULL); } return os; } template<typename T> ListNode<T> * LinkedList<T>::search(const T &value){ if(isEmpty()) return NULL; ListNode<T> *current = this->head; while(current != NULL){ if((*current).getValue().compare(value) == 0) return current; current = (*current).getNext(); } return NULL; } template<typename T> void LinkedList<T>::remove(const T &value){ ListNode<T> * toRemove = search(value); if(toRemove == NULL) return; ListNode<T> * before = this->head; ListNode<T> * after = (*this->head).getNext(); if(this->head == toRemove){ removeFromFront(); return; } else if(this->last == toRemove){ removeFromBack(); return; } while(after != toRemove){ before = after; after = (*before).getNext(); } after = (*after).getNext(); delete((*before).getNext()); (*before).next = after; } Output 1>------ Build started: Project: Oving10, Configuration: Debug Win32 ------ 1> main.cpp 1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::~LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??1?$LinkedList@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) referenced in function _main 1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class std::basic_ostream<char,struct std::char_traits<char> > &,class LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (??$?6V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$LinkedList@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) referenced in function _main 1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::insertAtBack(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?insertAtBack@?$LinkedList@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main 1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::LinkedList<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??0?$LinkedList@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) referenced in function _main 1>C:\Users\Håkon\documents\visual studio 2010\Projects\Oving10\Debug\Oving10.exe : fatal error LNK1120: 4 unresolved externals ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== Lenke til kommentar
GeirGrusom Skrevet 23. april 2012 Del Skrevet 23. april 2012 Kompilerer du med oving10template.cpp? Problemet her ser ut til å være at du bruker funksjoner som er deklarert men ikke definert. Lenke til kommentar
Antons1 Skrevet 23. april 2012 Forfatter Del Skrevet 23. april 2012 Den er lagt inn som en del av prosjektet hvis det er det du spør om? Det som er rart er at når akkurat de samme klassene er deklarert og definert for string og ikke som template så kompilerer og kjører programmet helt fint. Lenke til kommentar
GeirGrusom Skrevet 23. april 2012 Del Skrevet 23. april 2012 Ah vet hvorfor. Definer template funksjonene i headerfila. Lenke til kommentar
Valkyrex Skrevet 24. april 2012 Del Skrevet 24. april 2012 Stemmer det, siden template kode blir kompilert ved behov, og forskjellig når det brukes forskjellige steder, kan man ikke skille det ut i -h og -cpp filer. Forklares veldig bra på bunn av denne sia: http://www.cplusplus.com/doc/tutorial/templates/ Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå