命名包括警卫

Max*_*xpm 22 c++ include-guards c-preprocessor

C++如何包含通常命名的守卫?我倾向于看到这么多:

#ifndef FOO_H
#define FOO_H

// ...

#endif
Run Code Online (Sandbox Code Playgroud)

但是,我认为这不是很直观.如果没有看到文件名,就很难分辨出它的含义FOO_H和名称所指的含义.

什么是最佳做法?

Mat*_* M. 23

我个人遵循Boost的建议.它可能是最好的C++库集合之一,它们没有问题.

它像:

<project>_<path_part1>_..._<path_partN>_<file>_<extension>_INCLUDED

// include/pet/project/file.hpp
#ifndef PET_PROJECT_FILE_HPP_INCLUDED
Run Code Online (Sandbox Code Playgroud)

这是:

  • 合法(请注意,开头_[A-Z]或包含__不是)
  • 容易生成
  • 保证在项目中是唯一的(作为一个包含守卫)(否则你在同一个地方有两个文件)
  • 保证不会被用于其他任何东西(如果你结束另一个宏,INCLUDED你正在破坏战斗)

我读过关于GUID的内容,但那些看起来很奇怪.

显然,我宁愿所有编译器实现#pragma once(或更好,#pragma multiple"一次"是默认行为......)

  • @cmaster 在您拥有某些功能的 C 和 C++ 实现(分别使用 .h 和 .hpp 文件)的情况下,添加 _H 会很有帮助。 (2认同)

Nat*_*man 17

根据我自己的经验,惯例是在包含它们的头文件之后命名包含保护,除了名称全部为大写,并且句点用下划线替换.

因此test.h变得TEST_H.

真实的例子包括Qt Creator,它在自动生成类头文件时遵循此约定.

  • 最好只使用FILENAME_H作为包含保护名称,因为你保留所有项目的所有文件和所有库在同一目录中没有子目录,所以你知道他们从来没有冲突的文件名... (4认同)
  • 虽然这是常见的做法,但可能不够好,这取决于您的商店使用#defines和其他名称做什么. (2认同)

Mar*_*lon 13

直接来自谷歌的风格指南:

所有头文件都应该有#define防护,以防止多次包含.符号名称的格式应为<PROJECT> _ <PATH> _ <FILE> _H_.为了保证唯一性,它们应该基于项目源树中的完整路径.例如,项目foo中的文件foo/src/bar/baz.h应该具有以下保护:

 #ifndef FOO_BAR_BAZ_H_
 #define FOO_BAR_BAZ_H_
 ...
 #endif  // FOO_BAR_BAZ_H_
Run Code Online (Sandbox Code Playgroud)

我在自己的项目中使用这种风格.

  • 虽然一般来说谷歌编码标准是我见过的最糟糕的标准之一,但我确实使用了命名空间前缀.如果你在多个命名空间中有相同的名称,那绝对是必要的. (5认同)
  • @Toby 只是为了让它(更)独特......如果有人已经有一个`CONFIG_H`(比如一个包含的库),那么使用`CONFIG_H_` 不会与它发生冲突。同样的原因,有些人使用前导下划线,但他们不应该因为 thags 保留。 (2认同)
  • 链接已消失,现在更新为[https://google.github.io/styleguide/cppguide.html](https://google.github.io/styleguide/cppguide.html)。 (2认同)

cat*_*ive 5

查看#include是您的标题的代码.

如果它是这样的:

#include "mylib/myheader.h"
Run Code Online (Sandbox Code Playgroud)

mylib/myheader.h已经是一个独特的名字.只需大写和替换/和.用_

#define MYLIB_MYHEADER_H
Run Code Online (Sandbox Code Playgroud)

如果包含路径上有两个相对于包含路径具有相同名称的标题,则表明您已在该级别发生冲突.