2011-10-11 130 views
2

Possible Duplicate:
Why can templates only be implemented in the header file?C++(GCC):未定義的引用`堆棧<int> ::堆棧(INT)」

我這個掙扎了一段時間,我已經看到了幾個問題在這裏,但作爲C++新手我無法理解我錯在哪裏。

下面是代碼,我把它從this page,並試圖使其工作,但到目前爲止,我還沒有得到幸運:

stack.h

#ifndef STACK_H 
#define STACK_H 
template <class T> 
class Stack { 
    public: 
    Stack(int n); 
    ~Stack() { delete[] s; }; 
    private: 
    T* s; 
    int _top; 
    int _size; 
}; 
#endif // STACK_H 

堆棧。 CPP

#include "stack.h" 
template <class T> 
Stack<T>::Stack(int n) { 
    _size = n; 
    _top = -1; 
    s = new T[_size]; 
} 

的main.cpp

#include <iostream> 
#include "stack.h" 
using namespace std; 
int main() { 
    Stack<int> s(10); // undefined reference to `Stack<int>::Stack(int)' 
    return 0; 
} 

當我編譯器(gcc 4.5.2),我得到一個錯誤:undefined reference to Stack<int>::Stack(int)。我嘗試了幾件事,但沒有任何真正的知識來支持我所做的事情。如果有人能解釋我發生了什麼,我會非常感激。

+0

嗯,它不是重複的,但它確實解決了我的問題。我正在尋找錯誤('undefined reference'),所以我以前沒有找到這個問題。謝謝! – Janoma

+0

似乎有很多新人開始學習C++ ...... C++ 11的效果是什麼? – 2011-10-11 19:02:12

+1

@MarkB:5的規則? :) – 2011-10-11 19:03:04

回答

4

如果是特殊的定義,您只能在cpp文件中定義模板類定義 - 即您知道T是什麼。

除此之外,你的情況屬於這裏,你的模板類的所有定義必須放在頭文件中。每次新實例被聲明或定義時,編譯器都必須知道這些信息,因爲類型以及行爲會發生變化。 cpp文件中的定義意味着不同的翻譯單元,因此編譯器不可能知道您嘗試應用於模板的每個單獨的T的行爲。

+0

非常感謝。這很清楚,我現在明白了。 – Janoma

1

編譯器在創建模板類時必須具有所有相關信息,因此在其頭文件中完全實現了模板,通常

有幾種方法,你可以做到這一點,內聯函數,定義在頭文件模板的功能,其中包括在一個單獨的文件你的實現(在你的頭文件的末尾,有#include)等

這是一個similar question與更多的細節。

+0

有可能在cpp文件中有模板定義,請參見[this](http://stackoverflow.com/questions/7418553/private-template-functions/7418808#7418808) –

+0

不要在任何地方包含.cpp文件。 –

+0

這是可能的,但他們仍然需要實例化時具有所有的實現細節。我微妙地編輯了我的答案。 – Chad

1

「stack.cpp」中沒有什麼可以編譯的。模板只在實例化時才被編譯。因此,鏈接器無法找到這個從未編譯過的函數。

你不能用模板將頭文件和源文件中的聲明和實現分開。

你可以做的是將「stack.cpp」複製粘貼到「stack.h」的末尾。或者在「stack.h」的末尾包含「stack.cpp」,而不是其他方式,從而達到相同的效果。在後一種情況下,更改「cpp」文件的擴展名可能是明智的(參見Including .cpp at end of template header file