c ++模板和头文件

时间:2011-04-10 15:36:07

标签: c++ templates file header

所以,我听说C ++模板不应该分成标题(.h)和源(.cpp)文件。

例如,这样的模板:

template <class T>
class J
{   
   T something;
};

这是真的吗?为什么会这样?

如果由于这个原因,我必须将声明和实现放在同一个文件中,我应该把它放在.h文件还是.cpp文件中?

4 个答案:

答案 0 :(得分:26)

头。

这是因为模板在编​​译时实例化,而不是链接时,并且不同的翻译单元(大致相当于您的.cpp文件)在链接时只相互“了解”。在编译时,标题往往被广泛“了解”,因为你在任何需要它们的翻译单元中#include

阅读https://isocpp.org/wiki/faq/templates了解更多信息。

答案 1 :(得分:14)

你不能将模板化的类放入.cpp文件的原因是因为为了“编译”.cpp文件,你需要知道用什么类型来代替T.模板化的类(就像你的类J一样)没有足够的信息来编译。因此它必须全部在标题中。

如果您希望将实现分解为另一个文件以保持清洁,最佳做法是使用.hxx文件。像这样:在你的头文件里面,J.h,把:

#ifndef _J_H__
#define _J_H__

template <class T> class J{  // member definitions };

#include "j.hxx"

#endif // _J_H__

然后,在j.hxx中你将有

template <class T> J<T>::J() { // constructor implementation }

template <class T> J<T>::~J() { // destructor implementation }

template <class T> void J<T>::memberFunc() { // memberFunc implementation }

// etc.

最后在使用模板化类的.cpp文件中,让我们称之为K.cpp:

#include "J.h" // note that this always automatically includes J.hxx    
void f(void)
{
     J<double> jinstance;  // now the compiler knows what the exact type is.
}

答案 2 :(得分:4)

是的,这是真的。声明和实现通常一起放入头文件中。一些编译器尝试使用export关键字来允许它们分开,但是已经从C ++ 0x中删除了。查看this FAQ entry了解所有脏信息。

答案 3 :(得分:2)

如果您需要模板代码可供其他翻译单元(.cpp文件)使用,则需要将实现放在.h文件中,否则其他单元将无法实例化模板(展开它)根据他们使用的类型)。

如果模板函数仅在一个.cpp文件中实例化,则可以在那里定义它。当类具有作为模板的私有成员函数时(有时仅从实现文件调用,而不是类头文件),有时会发生这种情况。