#是否包含标题保护格式? 我知道它对一个项目没有什么区别,但是,假设你使用C++定义的头部守卫,你使用什么格式?e、 g.假设标题名为foo.hpp: #ifndef __FOO_HPP__ ... #ifndef INCLUDED_FOO_HPP ... #ifndef SOME_OTHER_FORMAT

#是否包含标题保护格式? 我知道它对一个项目没有什么区别,但是,假设你使用C++定义的头部守卫,你使用什么格式?e、 g.假设标题名为foo.hpp: #ifndef __FOO_HPP__ ... #ifndef INCLUDED_FOO_HPP ... #ifndef SOME_OTHER_FORMAT,c++,header,c-preprocessor,C++,Header,C Preprocessor,我对大写字母的概念很感兴趣,但无法确定这些卫士的格式。我总是使用INCLUDED\u FOO\u HPP 我不会使用双下划线,因为用双下划线开头是保留的。我使用 #if !defined(FOO_HPP_INCLUDED) <FILENAME_IN_ALL_CAPS>_<YYYYMMDD> 我更喜欢现代的定义的语法,因为它允许使用| |&&运算符,即使这里没有使用它们 也 从技术上讲是非法的,因为前导下划线是保留的。我总是使用 #ifndef FOOBAR_CPP

我对大写字母的概念很感兴趣,但无法确定这些卫士的格式。

我总是使用
INCLUDED\u FOO\u HPP

我不会使用双下划线,因为用双下划线开头是保留的。

我使用

 #if !defined(FOO_HPP_INCLUDED)
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>
我更喜欢现代的
定义的
语法,因为它允许使用| |&&运算符,即使这里没有使用它们

从技术上讲是非法的,因为前导下划线是保留的。

我总是使用

#ifndef FOOBAR_CPP

如果您使用的是Visual Studio或Microsoft编译器,请使用pragma方式

#pragma once

为了真正避免名称冲突,我使用guid:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
我喜欢这种格式:

#ifndef FOO_HPP
#define FOO_HPP

/* ... */

#endif // FOO_HPP
  • 一个简单的ifndef而不是if!已定义(…),因为对页眉保护使用复杂条件几乎没有意义
  • \u HPP用于将标识符标记为割台护罩的部件
  • 没有前导下划线,因为这样的标识符(以2个下划线或1个下划线和大写字母开头)是为实现保留的
  • 基本部分只是文件名,FOO。但是,对于要重用的库代码,建议在开始时添加另一部分。这通常是包含名称空间或“模块”名称,例如MYLIB_FOO_HPP,它有助于避免命名冲突

    • 就我个人而言,我只是使用文件名FOO_HPP。谷歌像SRC_ENGINE_FAST_HPP一样使用整个路径

      某些名称和函数集 签名始终保留给用户 实施:

      • 每个名称都包含一个双下划线(u u)或以 下划线后跟大写字母 信函(2.11)保留给 实现任何用途
      • 以下划线开头的每个名称都保留给 在中用作名称的实现 全局命名空间

      17.4.3.1.2/1

      我总是在include-guard中包含名称空间或相对路径,因为只有头名称被证明是危险的

      例如,您有一个大型项目,在代码的某个地方有两个文件

      /myproject/module1/misc.h
      /myproject/module2/misc.h
      
      因此,如果对include-guard使用一致的命名模式,那么最终可能会在这两个文件中定义
      \u MISC\u HPP\uu
      (发现此类错误非常有趣)

      所以我决定

      MYPROJECT_MODULE1_MISC_H_
      MYPROJECT_MODULE2_MISC_H_
      
      这些名字相当长,但与双重定义的痛苦相比,它是值得的


      另一种选择是,如果您不需要编译器/平台独立性,您可以寻找一些“pragma once”的东西。

      我也一直在使用一些类似的东西:

      #ifndef FOO_HPP
      #define FOO_HPP 1
      
      ...
      
      #endif
      

      正如大多数人所提到的,不要用双下划线来准备符号,因为C++是由C++标准为内部使用所保留的。

      您可能会想看看John Lakos的优秀著作《大规模C++软件设计》(为脚本KIDY链接纳粹而进行了消毒),其中一些关于页眉的考虑。

      干杯

      Rob

      我倾向于使用:

      #ifndef FILE_DATE_H_
      
      (用适当的延伸件(如水电站等)替换水电站)。日期戳是为了避免与其他方向/库中的其他同名标题发生冲突

      所以最后看起来是这样的:

      #ifndef SOMEFILE_20082411_H_
      

      当我为我的时间获得报酬,并且还没有公司标准时,我使用:

      #ifndef path_to_file_h
      #define path_to_file_h
      
      小写的原因是复制和粘贴文件名以及用下划线替换斜杠更容易。#ifndef的原因是它与#define很好地对齐,从而更容易看到符号是相同的。不过,我喜欢这个想法,所以我可能会尝试一下

      当我的时间没有报酬,也没有将代码发布到野外时,我只使用一次
      #pragma
      。与大多数其他可移植性问题不同,以后添加include-guard和现在一样容易,而且可以由对代码库一无所知的人来完成(例如,一年后的我,或者我将代码发送给某个无辜的程序员),因此YAGNI适用。

      我使用

       #if !defined(FOO_HPP_INCLUDED)
      
      <FILENAME_IN_ALL_CAPS>_<YYYYMMDD>
      
      _
      

      \u包括在内_
      
      保持它与文件夹层次结构的同步太烦人了(重构的朋友),guid太烦人了,日期后缀是。如果我必须在同一天同样命名文件,我会

      <FILENAME_IN_ALL_CAPS>_<YYYYMMDD>a
      <FILENAME_IN_ALL_CAPS>_<YYYYMMDD>b
      <FILENAME_IN_ALL_CAPS>_<YYYYMMDD>...
      
      \u a
      _b
      _...
      
      我会选择文件路径+包含的boost
      \u后缀,再加上现在广泛支持的
      \pragma once

      在很多编辑器中(对我来说,它是崇高的),您还可以为此定义一些宏/代码段

      这里有一个为您做这件事:

      <snippet>
          <content><![CDATA[
      #ifndef ${1:${TM_FILEPATH/(.*\/(include|src))*([^a-zA-Z0-9_]+)*([a-zA-Z0-9_]+)([.])*([a-zA-Z0-9_]+)*/\U$4_$6/ig}_INCLUDED}
      #define $1
      #pragma once
      
      
      $0
      
      
      #endif // $1
      ]]></content>
          <tabTrigger>incguard</tabTrigger>
          <description>include guard</description>
      </snippet>
      
      
      印加卫兵
      包括警卫
      
      所以
      yourproject/include/yourlib/yourfile.hpp

      变成
      YOURLIB\u yourlfile\u HPP\u include


      额外的外部源代码样式检查工具可以通过这种方式轻松跟踪您的防护的一致性。

      可能是因为这是不可移植的。使用pragma,但也要使用include-guard,以防将来需要使用不同的编译器。因为这样的代码会使您在与我的面谈中立即失败。请检查:即使您使用的是Visual Studio,您也应该尽可能遵守标准。@Shy,如果你在正确答案和正确资历方面让人失望,那么你可能不应该面试任何人。我支持这一点,只是我更喜欢在#define上使用与文件名相同的案例。在UNIX land(etc)中,FOO.HPP与FOO.HPP不同。不确定这是什么导致了否决票。这没有错,即使我总是用ifndef而不是!定义(),因为在此上下文中不需要使用| |或&。这有一种奇怪的意义:-)使用日期和时间