Ошибка компоновщика конструктора при использовании шаблона - PullRequest
1 голос
/ 20 декабря 2011

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

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

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;
}

connectedlist.h

#include "node.h"

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

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

connectedlist.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)" (??1?$LinkedList@H@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall LinkedList<int>::insert(int *)" (?insert@?$LinkedList@H@@QAEXPAH@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall LinkedList<int>::LinkedList<int>(void)" (??0?$LinkedList@H@@QAE@XZ) referenced in function _main

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

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

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

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

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

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

1 Ответ

4 голосов
/ 20 декабря 2011

Переместить материал из связанный список.cpp .. в связанный список.h

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

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


в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...