C ++如何包含通常命名的警卫?我倾向于看到这一点:
#ifndef FOO_H
#define FOO_H
// ...
#endif
但是,我认为这不是很直观。如果没有看到文件名,很难说出FOO_H
的含义及其名称所指的内容。
什么是最佳做法?
答案 0 :(得分:20)
我个人遵循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
和“一次”是默认行为......)
答案 1 :(得分:17)
根据我自己的经验,惯例是在包含它们的头文件之后命名包含保护,除了名称全部为大写,并且句点用下划线替换。
因此test.h
变为TEST_H
。
现实生活中的例子包括Qt Creator,它在自动生成类头文件时遵循此约定。
答案 2 :(得分:12)
直接来自google's style guide:
所有头文件都应该有#define 警卫,以防止多重包容。 符号名称的格式应该是 be&lt; PROJECT&gt; _&lt; PATH&gt; _&lt; FILE&gt; _H_。至 保证唯一性,他们应该 基于项目的完整路径 源树。例如,文件 项目foo中的foo / src / bar / baz.h 应该有以下警卫:
#ifndef FOO_BAR_BAZ_H_ #define FOO_BAR_BAZ_H_ ... #endif // FOO_BAR_BAZ_H_
我在自己的项目中使用这种风格。
答案 3 :(得分:5)
查看#include你的标题的代码。
如果是这样的话:
#include "mylib/myheader.h"
mylib/myheader.h
已经是一个独特的名字。只需大写和替换/和。用_
#define MYLIB_MYHEADER_H
如果您的包含路径上有两个相对于包含路径具有相同名称的标题,那么您已经在该级别发生了冲突。
答案 4 :(得分:3)
将FOO_H
替换为FOO_H_INCLUDED
,它更清晰。
答案 5 :(得分:2)
正如其他人之前提到的,一个非常常见的约定是使用名称的大写版本,并用下划线替换点:foo.h - &gt; FOO_H
但是,这可能导致名称与简单和/或通用名称冲突。因此,非空Visual 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
答案 6 :(得分:1)
我通常使用FOO_H_INCLUDED_
之类的东西。一些(微软)标题看起来很像GUID的字符串表示,但我从来没有需要任何精心设计的东西。
答案 7 :(得分:1)
通常人们通过文件名来执行此操作,以便每个文件的代码只编译并添加一次。您可以随心所欲地制作FOO_H,但几乎所有我编码或看过的东西都使用了文件名。只要确保它是独一无二的,因为你不希望你的FOO_H与别人的FOO_H冲突。
答案 8 :(得分:1)
我通常会查看它是什么时间,只是将其附加到它的末尾,即FOO_H_248
,这是一个额外的预防措施,无论如何你永远不必记住它,所以你不需要担心它很神秘。