2017-06-01 97 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