2013-12-09 28 views
0

繼續獲取未定義的參考,其他答案認爲應該是鏈接問題。我沒有正確編譯這個嗎?或者代碼中有什麼錯誤?我已經嘗試將main引入到stack.cpp中,並且它編譯並運行正常,但我不確定還需要做些什麼才能將main.o和stack.o鏈接起來,以及爲什麼它突然拋出一個合適的錯誤,我添加了這個文件。使用模板時未定義的參考

stack.h:

#ifndef STACK_INCLUDED 
#define STACK_INCLUDED 

#include <cstddef> 

template<typename T> struct Node { 
    Node(T _data, Node<T> * _next) : data(_data), next(_next) {} 
    T data; 
    Node<T> *next; 
}; 

template<class T> 
class Stack { 
private: 
    Node<T> *first; 
public: 
    Stack(void); 
    bool isEmpty(void); 
    void push(T n); 
    T pop(void); 
}; 

#endif 

stack.cpp:

#include "stack.h" 

template<class T> 
Stack<T>::Stack(void) { 
    first = NULL; 
} 

template<class T> 
bool Stack<T>::isEmpty(void) { 
    return first == NULL; 
} 

template<class T> 
void Stack<T>::push(T n) { 
    Node<T> *oldfirst = first; 
    Node<T> *newfirst = new Node<T>(n, oldfirst); 
    first = newfirst; 
    first->next = oldfirst; 
} 

template<class T> 
T Stack<T>::pop(void) { 
    T data = first->data; 
    first = first->next; 
    return data; 
} 

main.cpp中:

#include <iostream> 

#include "stack.h" 

using namespace std; 

int main(void) { 
    Stack<int> s; 

    if (!s.isEmpty()) { 
    cout << "not empty" << endl; 
    } 

    return 0; 
} 

嘗試編譯:

$ g++ stack.cpp -c 
$ g++ main.cpp -c 
$ g++ main.o stack.o 
main.o: In function `main': 
main.cpp:(.text+0x10): undefined reference to `Stack<int>::Stack()' 
main.cpp:(.text+0x1c): undefined reference to `Stack<int>::isEmpty()' 
collect2: ld returned 1 exit status 

回答

3

你不能像這樣使用單獨的編譯模板。編譯器需要在使用時查看模板定義(模板函數體),或者不知道如何爲Stack<T>::Stack()(等)的實例生成代碼。你可以明確地要求stack.cpp中的實例,但是最好將函數定義移動到頭文件中。

4

您需要在標題中包含整個模板類定義。

0

你可以從頭文件中分離實現,但你應該使用C++ 11中的'extern模板'。

+0

這是有效的,但它需要爲每個模板使用提供明確的專業化,這在一般編碼中非常繁瑣。它更經常用作優化。例如,標準庫的'basic_string'幾乎總是用作'basic_string ',而不是讓編譯器在每一個提到它的翻譯單元中實例化,然後讓鏈接器除了一個之外就扔掉,它通常在一個實例化源庫文件,''頭文件聲明它爲extern模板。 'basic_string'的其他用途通過通常的機制。 –