【问题标题】:c++ template and header files [duplicate]c ++模板和头文件[重复]
【发布时间】:2011-08-02 12:54:02
【问题描述】:

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

例如,这样的模板:

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

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

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

【问题讨论】:

标签: c++ templates file header


【解决方案1】:

标题。

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

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

【讨论】:

  • 这是本题最清晰的答案,也是原题
【解决方案2】:

您不能将模板类放入 .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.
}

【讨论】:

  • 我不确定.hpp 扩展的使用。按照惯例,在 C++ 中,.h.hpp 几乎可以互换,因此您不会给j.hpp 灌输一个在功能上与J.h 区分开来的文件名。 The convention here would be J.hxx.
  • +1 好点,我也一直在实践中使用.hxx(主要是通过别人的例子学习),但直到现在我才明白为什么它是正确的。
  • 如果我可以问,这有什么用?最后,如果.h .hxx 文件被修改,每个#include .cpp 文件都会被重新编译;并修改它在 .h 中的实现(不是这个例子;我的意思是当整个模板在 .h 中时)应该几乎相同,机械地,不是吗?
  • 它与编译器相同,只是我在实践中看到并且喜欢的约定。以我的经验,这只是分解实现的问题,这样您就可以拥有一个简短的 .h 文件,其中包含 .hxx 文件中模板化类的实现。如果您有相反的证据,请告诉我。
  • .hxx 的用途是什么?
【解决方案3】:

是的,这是真的。声明和实现一般都放在头文件中。一些编译器尝试了一个export 关键字,可以将它们分开,但已从 C++0x 中删除。查看this FAQ entry 了解所有肮脏的细节。

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      相关资源
      最近更新 更多