模板类源文件

Posted

技术标签:

【中文标题】模板类源文件【英文标题】:Template Class Source File 【发布时间】:2014-03-04 14:35:28 【问题描述】:

我一直在寻找一种分离模板类声明和定义的方法。我被推荐了一个解决方案,它在 Header.h 和 Source.cpp 中都包含防护,并且 Header.h 在包含防护的#endif 之后包含 Source.cpp。

我认为链接器会抱怨模板类的重新定义(多个符号?),但不知何故没有,为什么不呢?

这不会导致二进制结果中的重复代码吗?每次在源文件中包含头文件时,也会包含同一个类的定义。

【问题讨论】:

【参考方案1】:

对于普通符号,这确实会导致双重定义。但是,模板被区别对待,就好像它们具有内部链接一样。因此,没有双重定义。

但是,将实现放入 cpp 文件中显然是个坏主意——这会混淆许多工具链,它们按照惯例假定要编译此类文件。将文件重命名为 ipp - 这通常用于此类模板实现文件。

【讨论】:

【参考方案2】:

通过编译每个 CPP 文件创建的目标文件将包含重复项。链接器会删除这些重复项。

【讨论】:

【参考方案3】: 如果模板使用不同的参数进行实例化,则会创建不同的类。所以这不是重复。 如果参数相同,则链接器足够聪明,可以找到重复项。事实上,符合标准的编译器必须找到它们。

【讨论】:

【参考方案4】:

符号不是多重定义的,因为模板函数是内联的。

在 .cpp 文件中包含 .h 然后在 .h 文件中包含 .cpp 文件可以正常工作,因为 .h 文件有保护,因此头文件不包含 2 次。

总体而言,为此使用 .cpp 文件不是一个好主意,因为它非常令人困惑,简而言之,这与仅在 .h 文件中包含实现相同。您可以使用 _Impl.hpp 索引创建单独的 .hpp 文件来存储实现。

【讨论】:

【参考方案5】:

您还必须在实现文件中包含标头保护。无论如何都不要使用 .cpp,这很令人困惑。例如,我将声明放在 header.h 中,将实现放在 header-inl.h 中。

【讨论】:

以上是关于模板类源文件的主要内容,如果未能解决你的问题,请参考以下文章

基于 FreeMarker 模板配置一键生成目标类文件

基于 FreeMarker 模板配置一键生成目标类文件

模板类 error LNK2019: 无法解析的外部符号

C++:类模板分文件问题

visual studio 2015 修改类class 文件模板

当我将模板类与非模板类放在同一个 cpp 文件中时出现链接错误 - C++