2014-10-06 174 views
1

我正在为学校开发一个程序。这是一个使用模板的链接列表。模板链接列表编译错误

我有一个抽象基类:

#pragma once 
#include <string> 

using namespace std; 

template<class T> 
class LinkedListInterface 
{ 

public: 

    LinkedListInterface(void){}; 
    virtual ~LinkedListInterface(void){}; 


    virtual void insertHead(T value) = 0; 


    virtual void insertTail(T value) = 0; 


    virtual void insertAfter(T value, T insertionNode) = 0; 


    virtual void remove(T value) = 0; 


    virtual void clear() = 0; 


    virtual T at(int index) = 0; 


    virtual int size() = 0; 

}; 

和A类,我从它衍生出来的:

/* Linklist.h 
* 
* Created on: Oct 4, 2014 
    * 
    */ 

#ifndef LINKLIST_H_ 
#define LINKLIST_H_ 

#include <iostream> 
#include "LinkedListInterface.h" 

template<class T> 
class Linklist: public LinkedListInterface<T> { 
private: 
    struct _node 
     { 
      T val; 
      Linklist *next; 
     }; 
     struct _node node ; 
     Linklist *root = NULL; 
     Linklist *tail = NULL; 
     int _size = 0; 
     int finddup(T value); 
public: 
    Linklist(); 
    virtual ~Linklist(); 


    void insertHead(T value); 
     void insertTail(T value); 


     void insertAfter(T value, T insertionNode); 


     void remove(T value); 


     void clear(); 


     T at(int index); 


     int size(); 

}; 

#endif /* LINKLIST_H_ */ 

Linklist.cpp

/* 
    * Linklist.cpp 
    * 
    * Created on: Oct 4, 2014 
    *  
    */ 

#include "Linklist.h" 

template<class T> 
Linklist<T>::Linklist() 
{ 
    // TODO Auto-generated constructor stub 

} 

template<class T> 
Linklist<T>::~Linklist() 
{ 
    // TODO Auto-generated destructor stub 
} 

template<class T> 
int Linklist<T>::finddup(T value) 
{ 
    Linklist *tmp = root; 

    while (tmp) 
    { 
     if (tmp->node.val == value) 
     { 
      return 1; 
     } 
    } 

    return 0; 
} 


template<class T> 
void Linklist<T>::insertHead(T value) 
{ 
    Linklist *tmp = root; 

    if (finddup(value)) 
    { 
     return; 
    } 
    else 
    { 
     if (!root) 
     { 
      root = new Linklist<T>(); 
      root->val = value; 
      root->next = NULL; 
      tail = root; 
      _size++; 
     } 
     else 
     { 
      Linklist *newr = new Linklist<T>(); 
      newr->node.val = value; 
      newr->node.next = root; 
      root = &newr; 
      _size++; 
     } 
    } 

} 


template<class T> 
void Linklist<T>::insertTail(T value) 
{ 
    Linklist *tmp = root; 

    if (finddup(value)) 
    { 
     return; 
    } 
    else 
    { 
     if (!tail) 
     { 
      tail = new Linklist<T>(); 
      tail->val = value; 
      tail->next = NULL; 
      root = tail; 
      _size++; 
     } 
     else 
     { 
      Linklist *newr = new Linklist<T>(); 
      newr->node.val = value; 
      newr->node.next = NULL; 
      tail->node.next = &newr; 
      tail = &newr; 
      _size++; 
     } 
    } 

} 


template<class T> 
void Linklist<T>::insertAfter(T value, T insertionNode) 
{ 

    if (finddup(value)) 
    { 
     return; 
    } 
    else 
    { 
     Linklist *tmp = root; 
     while (tmp) 
     { 
      if (tmp->node.val == insertionNode) 
      { 
       Linklist *newr = new Linklist<T>(); 
       newr->node.val = value; 
       newr->node.next = tmp->node.next; 
       tmp->node.next = &newr; 
       _size++; 
       break; 
      } 
      else 
       tmp = tmp->node.next; 
     } 
    } 
} 


template<class T> 
void Linklist<T>::remove(T value) 
{ 
    Linklist *prev = NULL, *active = NULL; 

    if (!root) 
     std::cout << "List is empty" << std::endl; 
    else 
    { 
     if (root && root->node.val == value) 
     { 
      Linklist *t = root; 
      root = t->node.next; 
      delete t; 
      _size--; 
     } 
    } 
    prev = root; 
    active = root->node.next; 
    while (active) 
    { 
     if (active->node.val == value) 
     { 
      prev->node.next = active->node.next; 
      delete active; 
      _size--; 
      active = prev->node.next; 
     } 
     else 
     { 
      prev = active; 
      active = active->node.next; 
     } 
    } 

} 


template<class T> 
void Linklist<T>::clear() 
{ 
    Linklist *t = root; 
    while (t) 
    { 
     t = root->node.next; 
     delete root; 
     root = t; 
    } 
    root = NULL; 
    tail = NULL; 
    _size = 0; 

} 


template<class T> 
T Linklist<T>::at(int index) 
{ 
    Linklist *t = root; 

    if (index < _size) 
    { 
     for (int i = 0; i < _size; i++) 
     { 
      t = t->node.next; 
     } 
    } 
    else 
    { 
     t = NULL; 
    } 

    return (t); 

} 


template<class T> 
int Linklist<T>::size() 
{ 
    return (_size); 
} 

那些似乎是好。问题是当我尝试在提供和修改的工厂类中创建Linklist对象时。

#include "Factory.h" 

#include "Linklist.h" 



//You may add #include statements here 

/* 

    You will MODIFY THIS DOCUMENT. 

*/ 

/* 

    getLinkedListInt() and 

    Creates and returns an object whose class extends LinkedListInterface. 

    This should be an object of a class you have created. 

    Example: If you made a class called "LinkedList", you might say, "return new  LinkedList<int>();". 

*/ 

LinkedListInterface<int> * Factory::getLinkedListInt() 
{ 

    return new Linklist<int>(); 

} 



/* 
    getLinkedListString() and 

    Creates and returns an object whose class extends LinkedListInterface. 

    This should be an object of a class you have created. 

    Example: If you made a class called "LinkedList", you might say, "return new LinkedList<string>();". 

*/ 

LinkedListInterface<string>* Factory::getLinkedListString() 
{ 

    return new Linklist<string>(); 

} 

,有人告诉我:

undefined reference to `Linklist<int>::Linklist()' 

undefined reference to `Linklist<string>::Linklist()' 

当我编译。我不太了解模板,不知道我弄错了什么。

有没有人有任何建议?

感谢

+0

http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-固定 – CoryKramer 2014-10-06 20:05:42

回答

0

这是去上班:

的main.cpp

#include "Source.h" 

int main() { 
    Linklist<int> obj; 
} 

Source.h

#pragma once 

template <class T> 
class Linklist { 
public: 
    Linklist(); 
}; 

Source.cpp

#include "Source.h" 

template <class T> 
Linklist<T>::Linklist() {} 

输出:

错误LNK2019:无法解析的外部符号 “公用:__cdecl链表::链表(无效)”

出现这种情况,因为模板是如何被实例化。

在您的具体情况下,您可以明确实例化intstring类型,或者您可以更改设计以便在头文件中进行声明和定义。

欲了解更多信息:Why can templates only be implemented in the header file?