如何防止源文件依赖于头文件中的包含?

时间:2021-05-23 02:06:25
//Foo.h
#include <string>
struct Foo;

//main.cpp
#include "Foo.h"
int main(int argc, char *argv[])
{
  std::string s = "hello";
}

The problem I have with this code is that #include <string> leaks into main.cpp. #include <string> is needed in main.cpp to compile but if in a future version Foo.h doesn't need string anymore, main.cpp will not compile.

我对此代码的问题是#include 泄漏到main.cpp中。 main.cpp中需要#include 来编译,但如果在以后的版本中Foo.h不再需要字符串,则main.cpp将无法编译。

Is there a way to prevent this?

有办法防止这种情况吗?

Edit: I know that I can manage this on my own by always including every file that I need but I am working in a team and everyone does their own thing and it is a complete mess. So I was wondering if there is a way to force this.

编辑:我知道我可以自己管理这个,总是包括我需要的每个文件,但我在团队中工作,每个人都做自己的事情,这是一个完整的混乱。所以我想知道是否有办法强制这样做。

Comments seem to indicate that we have to manage it manually. I guess this answers my question.

评论似乎表明我们必须手动管理它。我想这回答了我的问题。

2 个解决方案

#1


4  

No, there is no automated way to protect yourself from inadvertently relying on headers that you've included through other headers.

不,没有自动方法来保护自己免于无意中依赖于您通过其他标头包含的标头。

What you need to do is discipline yourself to include the relevant headers in each source file that uses them, even if each #include directive isn't strictly required in each source file.

您需要做的是遵守自己,在每个使用它们的源文件中包含相关标头,即使每个源文件中并不严格要求每个#include指令。

The consequences of forgetting that aren't dire, though. If Foo.h eventually changes to no longer include string, then the code will fail to compile, but the fix is easy and takes almost no time. It's not worth worrying about.

但遗忘的后果并不严重。如果Foo.h最终更改为不再包含字符串,那么代码将无法编译,但修复很容易并且几乎没有时间。这不值得担心。

#2


2  

Let every file include only the dependencies it really needs. Also you should protect your own header files using include guards (C++ #include guards).

让每个文件只包含它真正需要的依赖项。您还应该使用include guard(C ++ #include guards)来保护自己的头文件。

Foo.h:

#ifndef _INCLUDED_FOO_H_
#define _INCLUDED_FOO_H_ 

// Only #include <string> here if it is needed in the Foo.h
// ...
struct Foo;
// ...

#endif

main.cpp:

#include <string>
#include "Foo.h"
int main(int argc, char *argv[])
{
   std::string s = "hello";
}

This way main.cpp does still compile even if Foo.h changes later.

这样,即使Foo.h稍后更改,main.cpp仍会编译。

#1


4  

No, there is no automated way to protect yourself from inadvertently relying on headers that you've included through other headers.

不,没有自动方法来保护自己免于无意中依赖于您通过其他标头包含的标头。

What you need to do is discipline yourself to include the relevant headers in each source file that uses them, even if each #include directive isn't strictly required in each source file.

您需要做的是遵守自己,在每个使用它们的源文件中包含相关标头,即使每个源文件中并不严格要求每个#include指令。

The consequences of forgetting that aren't dire, though. If Foo.h eventually changes to no longer include string, then the code will fail to compile, but the fix is easy and takes almost no time. It's not worth worrying about.

但遗忘的后果并不严重。如果Foo.h最终更改为不再包含字符串,那么代码将无法编译,但修复很容易并且几乎没有时间。这不值得担心。

#2


2  

Let every file include only the dependencies it really needs. Also you should protect your own header files using include guards (C++ #include guards).

让每个文件只包含它真正需要的依赖项。您还应该使用include guard(C ++ #include guards)来保护自己的头文件。

Foo.h:

#ifndef _INCLUDED_FOO_H_
#define _INCLUDED_FOO_H_ 

// Only #include <string> here if it is needed in the Foo.h
// ...
struct Foo;
// ...

#endif

main.cpp:

#include <string>
#include "Foo.h"
int main(int argc, char *argv[])
{
   std::string s = "hello";
}

This way main.cpp does still compile even if Foo.h changes later.

这样,即使Foo.h稍后更改,main.cpp仍会编译。