模板类源文件
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 中。
【讨论】:
以上是关于模板类源文件的主要内容,如果未能解决你的问题,请参考以下文章