2013-09-26 67 views
0

我最近決定通過編寫簡單的結構來簡化C++開發來做一些個人C++實踐。我的第一個嘗試是編寫一個簡單的LinkedList,但將其定義爲模板類,以便它可以處理多種數據類型。在做這件事時,我做了一個在頭文件中定義類並在cpp文件中實現它的標準實踐,然後使用make來構建它(使用686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1)。至於構建C++文件(其中包括一個Node.cppLinkedList.cppLinkedListIterator.cpp一切正常,沒有投訴,然後我介紹main.cpp其中包含主要方法,並試圖創建LinkedList<string>(工作),然後試圖稱它的長度函數我都定義和實現:如何在C++中正確定義和實現模板類?

// Other code here 
LinkedList<string> *list = new LinkedList<string>(); 
cout << "Initial length: " << list->length() << endl; 
delete list; 
list = NULL; // I had defined NULL to be 0, pre 4.6 compiler so nullptr wasn't available 
// End the main function 

這扔,沒有length()功能是爲模板LinkedList<string>類中定義的錯誤,所以我就開始了我的研究,我瞭解到,模板類不能在標準頭/執行定義格式就像標準的C++類一樣,但是這些響應都沒有(主要在這裏)解決了如何正確處理模板類爲了完成我的個人練習,我放下了頭文件,並在cpp文件中定義並實現了這些類。在那裏一切正常。

有一些「解決方法」,可能會將實現與定義分開,例如在頭文件末尾包含cpp文件(這對我無效),或者如果您只希望您的類與特定類型的工作,在喜歡你的頭文件的基本申報類的靜態模板版本:

// Define a template class 
template LinkedList<string>; 
template LinkedList<int>; 
// etc... 

這是我沒有嘗試(它可能已經工作,和我只是做了個人運動這是完全可以接受的),因爲這只是感覺不對。爲什麼要將一個模板類鎖定到某些類型中?我意識到你可以很容易地將它鎖定到你需要的所有主要類型,給你一個數據類型的定義,但是這樣做並不適合我。

TL; DR最終,我的問題是,定義模板類並在其他人將使用的某種應用程序/庫中實現模板類的正確方法是什麼?

回答

3

您需要將所有類 - 類定義類代碼 - 放在標題中。想知道爲什麼,想象一下一個簡單的例子:

// in .hpp 
template <typename T> 
T increment(T x); 

// in .cpp 
template <typename T> 
T increment(T x) { return x + 1; } 

現在你只編譯一次.cpp。它應該爲increment函數生成什麼代碼? +運算符可能是浮點加法,或整數加法,或短整數,或者甚至是重載的operator+

然後想想其他的。在您使用的increment功能是CPP文件:

// some other .cpp file 
#include "increment.hpp" 
... 
    increment(a); 

點,編譯器知道a是什麼類型的,這樣的話它可能產生的increment功能正確的代碼。但它不知道increment函數是什麼樣子,因爲它只能看到.hpp文件,而increment的代碼位於.cpp文件中。

因此,使其工作的唯一方法是將聲明和代碼放在.hpp文件中,以便每次使用時,您都有該定義,並且編譯器可以生成正確的版本鍵入您正在使用的。

+0

這是一個很好的解釋,但我會多說一點代碼組織。我看到的一種做法是將標題分割成單獨的文件 - 一個以.h結尾,另一個以.hpp結尾。 .h文件將聲明接口,然後在最後包含.hpp文件。這提供了聲明和定義之間的明確分離。我認爲'#include'頭文件中的.cpp文件可能會令人困惑,因爲.cpp文件通常被認爲是一個完整的翻譯單元,但是通過讓它包含一個模板定義,它實際上不是。 –

2

模板在實例化處必須是可見的。如果沒有明確的實例化,這基本上意味着成員函數定義必須在頭中可供其他翻譯單元實例化。

+0

因此,不要在cpp文件中做所有事情,只要在頭文件中進行定義和實現? –

+1

它有助於將「成員函數定義」看作「成員函數定義**模板**」。它們不是功能;他們是製作函數的模式,所以不要單獨編譯。 –

+0

@PeteBecker好吧,這更有意義。 –

相關問題