2011-12-20 2 views
1

Я только начал использовать шаблон.Ошибка компоновщика компоновщика с использованием шаблона

Я хочу создать класс связанного списка, который хранит адрес Type (может быть объектом). Вот схема моего проекта:

linkedlist.h 
node.h 
node.cpp 
linkedlist.cpp 
main.cpp 

node.h

template <class Type> struct Node 
{ 
public: 
    Node<Type>(); 
    Node<Type>(Type* x = 0, Node* pNext = 0); 
    Type* data; 
    Node* next; 
}; 

node.cpp

#include "node.h" 

template<class Type> Node<Type>::Node() 
{ 
    next = 0; 
    data = 0; 
} 
template<class Type> Node<Type>::Node(Type* item, Node* ptrNext) 
{ 
    next = ptrNext; 
    data = item; 
} 

linkedlist.h

#include "node.h" 

template <class Type> class LinkedList 
{ 
private: 
    Node<Type>* root; 

public: 
    LinkedList<Type>(); 
    ~LinkedList<Type>(); 
    void insert(Type*); 
    void remove(Type*); 
}; 

linkedlist.cpp

#include "linkedlist.h" 

template <class Type> LinkedList<Type>::LinkedList() 
{ 
    root = 0; 
} 

template <class Type> LinkedList<Type>::~LinkedList() 
{ 
    Node* p; 
    while(p = root) 
    { 
     root = p->next; 
     delete p; 
    } 
} 
// many more.... 

В main.cpp, у меня есть следующие:

int main() 
{ 
    int *ptrA, *ptrB; 
    int a = 100, b = 10; 

    ptrA = &a; 
    ptrB = &b; 

    LinkedList<int>myList; 
    myList.insert(ptrA); 
    return 0; 
} 

и компилятор бросил ошибки компоновщика:

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<int>::~LinkedList<int>(void)" ([email protected]@@[email protected]) referenced in function _main 
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall LinkedList<int>::insert(int *)" ([email protected][email protected]@@[email protected]) referenced in function _main 
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<int>::LinkedList<int>(void)" ([email protected]@@[email protected]) referenced in function _main 

Попытка решения:

Я позвонил LinkedListmyList() вместо этого. Это может устранить ошибку компоновщика, но я не смогу вызвать какую-либо функцию-член.

myList.insert (ptrA) скажет: «Ошибка: выражение должно иметь тип класса», если я положил().

Так ясно, что это не работает.

В чем проблема? Я думаю, что вся реализация имеет проблемы ....

Спасибо за ваше время.

+1

Возможный дубликат [Почему шаблоны могут быть реализованы только в файле заголовка?] (Http://stackoverflow.com/questions/495021/why-can-templates-only -be-implement-in-the-header-file) – Flexo

+0

или http://stackoverflow.com/questions/3705740/c-lnk2019-error-unresolved-external-symbol-template-classs-constructor-and или http://stackoverflow.com/questions/3680312/linker-error-lnk2019 – Flexo

+0

Кажется, домашнее задание. Какой компилятор? – Geoffroy

ответ

3

Перемещение вещи из linkedlist.cpp .. в linkedlist.h

Как это объявить «шаблон для создания коды» машинный код фактически не существует, пока вы не дать компилятору типа, который вы хотите использовать ,

Например, если весь код шаблона виден компилятору, как только вы идете: LinkedList<int>myList, компилятор создает сплошной реальный класс, который создает связанный список из ints. В вашем случае компилятор не может видеть код шаблона, поэтому он не может сгенерировать машинный код.


в C++ 11 вы можете сказать «Экстерн шаблон»: http://en.wikipedia.org/wiki/C%2B%2B11#Extern_template

в заголовочном файле, а затем реализовать версию «Int» в файле linkeList.cpp .. и это будет доступный в main.cpp, когда он пытается его использовать.

Это дает преимущество компилятора, который не должен генерировать машинный код в каждом.cpp-файл, в котором используется шаблон, и делает компиляцию быстрее.

Это можно сделать в C++ 98 тоже .. но это немного сложнее, а не на 100% портативном, насколько я понимаю ... проще всего генерировать код повсюду. Вот хороший комментарий для gnu gcc: http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html

+0

Большое вам спасибо. Вы просто спасли меня, когда стучали головой! –

Смежные вопросы