如果目标文件已经有头保护,我们应该用#ifndef 保护#include 吗?

Should we guard #include with #ifndef if the targeted file already has header guard?

假设我们有两个 class,Foo 和 Bar。

在Foo.h

#ifndef MYPROJ_FOO
#define MYPROJ_FOO
....
# endif 

在Bar.cpp中,是否还需要保护include如

#ifndef MYPROJ_FOO
#include <Foo.h>
#endif

或简单的 #include 就足够了吗?如果我们已经有了头球后卫,我觉得包括后卫似乎是多余的,但我经常看到这种做法,因此想知道我是否遗漏了什么。谢谢!

不,你不应该。包含守卫用于 headers,它们被其他文件包含。另一方面,源文件永远不应包含在其他文件中。

或者,您可以考虑在 header 文件中使用(非标准但普遍接受的)扩展名

#pragma once

在功能上,它没有任何区别。

旧代码可能使用它的原因是为了优化。这意味着预处理器可以避免读取 Foo.h 第二次,因此它可以更快地生成结果。

如今,即使预处理器确实第二次读取文件,其对性能的影响也应该足够小,不必理会它。一些预处理器甚至可以自动检测头文件保护,记住哪个头文件保护与哪个宏相关联,并避免 re-reading 头文件完全靠自己。

or simple #include is sufficient?

是的,是的。

It seems redundant to me to have include guard if we already have header guard,

是的,完全多余。

but I see such practice quite often

我看不到这样的做法,除非代码作者不知道他们在做什么。

in Bar.cpp, do we still need to guard the include such as

#ifndef MYPROJ_FOO
#include <Foo.h>
#endif

or simple #include is sufficient?

从正确性的角度来看,简单的 #include 就足够了。

It seems redundant to me to have include guard if we already have header guard, but I see such practice quite often, hence wondering if I'm missing something.

John Lakos 在他的书中推荐了这种做法 Large Scale C++ Software Design

但是,更好的替代方法是使用大多数现代 C++ 编译器都支持的 #pragma once 指令。

Foo.h:

#pragma once
....

那你就可以用

#include "Foo.h"

在任何 .cpp 文件中。