Gå til innhold

Templates i headerfil


Anbefalte innlegg

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
Videoannonse
Annonse

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

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...