«Неопределенная ссылка на» ошибка функции - PullRequest
3 голосов
/ 23 октября 2011

Я получаю действительно расстраивающую ошибку, с которой я боролся в течение некоторого времени.

У меня была программа, которая работала нормально, прежде чем я начал менять тип данных с int на использование шаблонов.Это ошибка, которую я получаю:

g++ -c UseList.cpp
g++ -c List.cpp
g++ UseList.o List.o -o UseList
UseList.o: In function `main':
UseList.cpp:(.text+0xee): undefined reference to `List<int>::addtofront(int)'
UseList.cpp:(.text+0x10b): undefined reference to `List<int>::show()'
collect2: ld returned 1 exit status
make: *** [UseList] Error 1

Соответствующие части моего кода приведены ниже.Пожалуйста, дайте мне знать, что это может быть.Я совершенно невежественен.Спасибо!

UseList.cpp:

#include <iostream>
#include <cstdlib>
#include "List.h"
using namespace std;

int main (int argc, char *argv[]) {
    cout << "-----------------------------------------" << endl;
    cout << "----------------LIST ONE-----------------" << endl;
    cout << "-----------------------------------------" << endl;

    List<int> *list1;

    srand(time(NULL));

    cout << "# Add 3 random ints to the front:" << endl;
    for(int i=0;i<3;i++){
        list1->addtofront(rand() % 10000);
    }
    list1->show();
}

List.h

#include <iostream>
using namespace std;

#ifndef LIST
#define LIST

template <class L>
class Node {
   public:
        // constructors and destructors
       Node<L>(L data);
       Node();
       Node<L>(const Node<L> &n);

        // components of a node
       L data;  
       Node *next;
       Node *prev;
};

template <class L>
class List
{
   private:
        Node<L> *first;
        Node<L> *last;
        int num_elements;
   public:
        // constructors and destructors
        List();
        ~List();
      List<L>(const List<L> &l);

        List *addtofront(L);                
        void show();
    [...] // unnecessary code removed
};

// #include "List.cpp"
#endif

List.cpp

#include "List.h"
using namespace std;

// -------------------------------------
// ------------Node class---------------
// -------------------------------------

template <class L>
Node<L>::Node(L data_input) {
   data = data_input;
   next = 0;
   prev = 0;
}

template <class L>
Node<L>::Node() {}

template <class L>
Node<L>::Node(const Node<L> &n) {
    data = n.data;
    next = n.next;
    prev = n.prev;
}


// -------------------------------------
// ------------List class---------------
// -------------------------------------

template <class L>
List<L>::List() {
    first = NULL;
    last = NULL;
   num_elements = 0;
}

template <class L>
// Appends data to the front of the list.
List<L> *List<L>::addtofront(L data) {
    Node<L> *new_node = new Node<L>(data);
    if(first == 0 && last == 0) {
        first = new_node;
        last = new_node;
    } else {
        // there will be no previous since
        // it is the first
      new_node->next = first;
        first->prev = new_node;
      first = new_node; 
    }
    num_elements++;
}

template <class L>
// Append data to the end of the list.
List<L> *List<L>::addtoback(L data) {
    [...]
}

template <class L>
// Return a pointer to a copy of the first item in the list.
Node<L> *List<L>::getfirst() {
    [...]
}

template <class L>
// Return a list of all but the first element of the original.
List<L> List<L>::getrest() {
    [...]
}

template <class L>
// Print out the data in each node separated by a space.
void List<L>::show() {
    Node<L> *current_node = first;
    while (current_node != NULL) {
       cout << current_node->data << " ";
       current_node = current_node->next;
    }
    cout << endl;
}

template <class L>
// Returns a reversed version of toReverse
List<L> List<L>::reverse(List toReverse) {
      [...]
}

Ответы [ 4 ]

2 голосов
/ 23 октября 2011

Вам нужно поместить все реализации шаблона в заголовочный файл.Поскольку компилятор не будет знать, какой тип может иметь функция, он не может скомпилировать файл cpp.Так что переместите все содержимое из List.cpp в List.h, и оно должно работать.

1 голос
/ 23 октября 2011

Функции шаблона должны оставаться в том же блоке данных, который вы будете использовать.Это связано с тем, что шаблоны не объявляют типы напрямую, они создаются при использовании.

Поместите реализацию шаблона в заголовочные файлы.

Вы можете переименовать файл "list.cpp" в файл с именем"list.hpp" и включить его в "list.h".Кто-то использует также соглашение "list.inc"

0 голосов
/ 23 октября 2011

Это все?

List.h:

template <class L>
class List
{
        /* ... */
        List *addtofront(L);

Но в List.cpp:

template <class L>
// Appends data to the front of the list.
List<L> *List<L>::addtofront(L data) {

Я вижу List* и List<L> *.

0 голосов
/ 23 октября 2011

Должно работать лучше, если ваша ссылка выглядит следующим образом:

g ++ List.o UseList.o -o UseList

...