2017-06-01 94 views
1

比方說,我們有基類表是從模板C類可能繼承++專業對自己

template <typename T> 
class Table 
{ 
public: 
    Table(); 
    virtual ~Table() = default; 
private: 
// get all column names as list 
virtual std::list<std::string> getAllColumnsImpl(); 
}; 

,我想繼承TestTable的類和重寫方法getAllColumnsImpl從基類:

class TestTable : 
public Table<TestTable> 
{ 
public: 
TestTable(); 
virtual ~TestTable() = default; 

std::string Description; 
int Count; 


private: 
// get all column names as list 
std::list<std::string> getAllColumnsImpl() override; 
}; 

一般情況下可以嗎?

比如我有這樣的鏈接錯誤:

error LNK2019: unresolved external symbol "public: __cdecl Table<class TestTable>::Table<class TestTable>(void)" ([email protected]@@@@[email protected]) referenced in function "public: __cdecl TestTable::TestTable(void)" ([email protected]@[email protected]) 
+0

您不能覆蓋私有成員函數,它必須被「保護」。 –

+0

@Someprogrammerdude - 同樣的錯誤... – Alexander

+0

@Someprogrammerdude - Jason Lang給出的答案,這正是CRTP - 我的問題在這裏有答案https://stackoverflow.com/questions/4173254/what-is-the-curiously- recurring-template-pattern-crtp - 但我之前不知道CRPT - 因爲找不到有關信息 - 可能是我的問題可以幫助像我這樣的人... – Alexander

回答

1

你可以做到這一點,這就是所謂的CRTP - 的奇怪循環模板參數。它非常方便,並且有許多博客和資源可以解釋它的用途。

你得到的錯誤是因爲你需要在模板的頭文件中有模板的函數體。

每個cpp文件被編譯爲一個單獨的目標文件,並且模板以每個cpp文件爲基礎進行解析。當你將模板代碼放在一個cpp文件中時,它只是「template < T>」,編譯器不知道T是什麼,所以不會生成代碼(除非它是從同一個cpp文件請求的,實際類型和不是T)。

但是,您的其他cpp文件知道它想要一個「模板< TestTable>」,但它無法訪問將使其工作的代碼,因爲它卡在另一個cpp文件中,該文件只知道通用「模板< T>」。這兩個cpp文件都不能生成缺少的代碼,所以你會得到鏈接器錯誤。將所有模板代碼放在頭文件中可以解決問題。

+0

謝謝 - 我發現在這裏舉例說明https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp – Alexander