25

C++ 包含守卫通常是如何命名的?我经常看到这个:

#ifndef FOO_H
#define FOO_H

// ...

#endif

但是,我认为这不是很直观。如果没有看到文件名,就很难知道它的FOO_H用途和它的名称所指的内容。

什么是最佳实践?

4

9 回答 9

27

我个人遵循 Boost 的建议。它可能是最大的高质量 C++ 库集合之一,而且它们没有问题。

它是这样的:

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

// include/pet/project/file.hpp
#ifndef PET_PROJECT_FILE_HPP_INCLUDED

这是:

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

我读过有关 GUID 的信息,但那些看起来很奇怪。

显然我宁愿不是所有编译器都实现#pragma once(或者更好,#pragma multiple并且“曾经”是默认行为......)

于 2011-02-02T07:53:22.173 回答
22

根据我自己的经验,约定是在包含它们的头文件之后命名包含保护,但名称全部大写并且句点替换为下划线。

就这样test.h变成了TEST_H

现实生活中的示例包括 Qt Creator,它在自动生成类头文件时遵循此约定。

于 2011-02-01T20:28:08.070 回答
15

直接取自谷歌的风格指南

所有头文件都应该有#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_

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

于 2011-02-01T20:34:32.330 回答
5

查看#include 是您的标头的代码。

如果是这样的:

#include "mylib/myheader.h"

mylib/myheader.h已经是一个唯一的名称。只需大写并替换 / 和 。和 _

#define MYLIB_MYHEADER_H

如果您的包含路径上有两个与包含路径具有相同名称的标头,则您已经在该级别发生了冲突。

于 2011-02-01T23:00:39.543 回答
4

替换FOO_HFOO_H_INCLUDED,它更清晰。

于 2011-02-01T20:27:03.757 回答
2

正如其他人之前提到的,一个非常常见的约定是使用大写版本的名称,并将点替换为下划线: foo.h -> FOO_H

但是,这可能会导致名称与简单和/或通用名称发生冲突。因此,非空 Visual C C++ 项目中的 stdafx.h 等自动生成的标头会附加一些随机字符串,例如:

#ifndef FOO_H__NsknZfLkajnTFBpHIhKS
#define FOO_H__NsknZfLkajnTFBpHIhKS
#endif

http://www.random.org/strings/是一个有用的随机生成器。

另外,如果文件是某个子模块的一部分,或者它的内容位于一个特定的命名空间中,我倾向于将其添加到保护中:

#ifndef SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS
#define SOMECOMPONENT_FOO_H__NsknZfLkajnTFBpHIhKS

namespace somecomponent
{
  ...
}

#endif
于 2011-02-01T21:06:11.200 回答
1

我通常使用类似FOO_H_INCLUDED_. 一些(Microsoft)标头看起来很像 GUID 的字符串表示形式,但我从来不需要如此复杂的东西。

于 2011-02-01T20:27:01.553 回答
1

通常人们通过文件名来做这件事,这样每个文件的代码只会被编译和添加一次。你可以随心所欲地制作 FOO_H,但我曾经编码或看到的几乎所有东西都使用了文件名。只要确保它是唯一的,因为您不希望您的 FOO_H 与其他人的 FOO_H 冲突。

于 2011-02-01T20:28:23.207 回答
1

我通常会查看现在是什么时间,然后将其附加到它的末尾,即FOO_H_248,这是一种额外的预防措施,无论如何您都不必记住它,因此您不必担心它是神秘的事实。

于 2011-02-01T20:48:41.637 回答