我应该在.cpp和.h文件中重复包含吗?

8

Scenario:

foo.h:

#include <vector>

class foo {
  public:
  std::vector<int>* getVector();

  /* ... other methods declarations ... */

}

foo.cpp:

#include "foo.h"
#include <vector>

/* ... other methods definitions using std::vector ... */

std::vector<int>* foo::getVector() {
  return new std::vector<int>();
}

我希望.cpp文件不会受到头文件未来变化的影响。如果类的接口由于某种原因发生更改,并且可以消除对的依赖性,那么我可能会冒险使.cpp中的其他方法也失去该包含。

在.cpp和.h文件中都重复包含是否正确?这种做法有意义吗,还是应该只依赖于头文件中的包含?


3
请具体说明每个文件需要包含什么内容。另外,顺便提一下,你漏掉了模板参数。 - chris
谢谢你的建议,那正是我所想的。但是我不明白你所说的“你缺少模板参数”的意思。 - Andrea Casaccia
是的,最好不要放代码,因为它与问题无关,会引来很多关于代码质量的评论。 - Keith Layne
2
过于争论,我认为任何好的答案都会在争吵中失去(这太糟糕了)。 - Ben Voigt
@chris 我知道这不是问题的关键,但只是为了学习:你为什么说这段代码中的指针是不必要的呢? - Andrea Casaccia
显示剩余6条评论
4个回答

17

只包含你需要的内容,不多也不少。

在多个.h文件和多个.cpp文件中包含相同的头文件本身并不是问题。头文件保护指令(Header guards)可以有效地解决多次包含文件引起的问题。

如果你试图避免多次包含相同的文件,实际上可能会产生负面影响,因为这通常会导致一个“mega-include文件”,其中包括整个项目所需的所有内容。这很糟糕,因为对任何一个头文件的更改都会导致所有文件重新编译。

如果你担心.h/.cpp文件同时包含相同的文件,请遵循以下准则:

  • 如果头文件中不需要包含该文件,则只在CPP文件中包含它
  • 如果需要在头文件中使用类声明(但未使用),请在.h文件中使用前向声明,并在CPP文件中包含它。
  • 如果你确实在头文件中使用了该包含文件,则将其包含在头文件中而不是CPP中。

1
+1:为了更明确,在您的情况下,由于您无法前向声明std::vector,因此应将其包含在头文件中而不是cpp文件中。 - David Rodríguez - dribeas
@TimothyShields,这个项目符号列表实际上只是从Google的C++代码指南中适应过来的http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml - riwalk

1
不应该这样做。这没有任何意义。冗余的代码只会增加成本而无法带来好处。
每个文件都应该包含所需内容,而不是更多。在您特定的情况下,头文件及其实现,.cpp 中的冗余声明并没有帮助。如果头文件发生了足够的变化,使得函数不再需要返回一个向量,则您仍然需要重新审视 .cpp 文件。

1
遵循这个建议会自然地导致超级包含文件,这可能会大大增加编译时间。请参考我的答案。 - riwalk
@Star 怎么做呢?.h 文件应该只包含它所需的内容,.cpp 文件应该先包含 .h 文件,然后再包含它所需的内容。重复是没有帮助的。 - Alan Stokes
@Alan 实际上,我在尝试分析的情况是当.h和.cpp文件都需要同一个文件时。 - Andrea Casaccia
好的,这样想:假设有5个cpp文件都包含(并使用)相同的3个头文件。根据你所说的字面意思,我应该将这3个包含移到“通用包含”文件中以避免重复,对吗?不对。这样做会诱使人们包含元包含文件而不是实际文件,从而增加了小改动的编译时间。 - riwalk
根据您的评论,似乎您本能地知道如何做到这一点,但是您的回答表明您采用了一种过于宽泛的策略。 - riwalk
显示剩余2条评论

1
在 .cpp 文件中,只需要包含与实现相关的内容(实际上就是 .cpp 文件),而不需要重复包含已经在头文件中包含的内容。这样,当有人查看您的代码时,他也能更好、更清晰地理解您的代码。
知道哪些依赖项仅适用于实现可能非常有用,例如在升级/替换它时(同时保留接口)。

1
尽可能少地在头文件中包含文件,并仅在需要它们的.cpp文件中包含它们。您的foo.h头文件可能会被包含在许多其他不需要来自其他头文件(在这种情况下为vector.h)的声明的.cpp文件中,这最终会导致更长的编译时间和不太清晰的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接