C ++的有效用途还包括防守,包括防护?

这个问题是讨论C ++命名约定的几个问题之一。提出这个问题的人认为这个命名约定:
#ifndef FOO_H
#define FOO_H

// ...

#endif
单独采取时有点不直观(
FOO_H
是什么意思?)我倾向于同意。 其他人说,除非需要添加更多东西以更好地避免碰撞(例如
PROJECTNAME_FOO_H_SDFFGH69876GF
),名称
FOO_H
就好了,因为从上下文中可以清楚地知道它的目的是什么(即,它位于同名文件的开头)并且很明显它是一个包括警卫队员。 我可以买这个,如果有
FOO_H
的唯一目的是防止多重包含,但有条件我想在文件的其他地方有
FOO_H
吗?我认为条件编译是一个很好的理由,在这种情况下命名为
FOO_H_INCLUDED
会更清楚。 是否有类似于此的直接使用,或者我应该避免重新利用包含警卫?     
已邀请:
我认为这个问题本身就存在缺陷。术语“防护”是指
#define
s,并且在防止多重包含的特定用途中检查
#defined
,这也是唯一的用途。 现在更一般地说,定义和条件编译可以用于其他事情,比如编写与平台相关的代码,并且只会在某些情况下编译... 无论是
FOO_H
还是
FOO_H_INCLUDED
更好,我总是说后者是最具表现力的,然后我会回到
vi
并在我的下一个
foo.h
标题中输入
FOO_H
。同样,正如我在另一个问题的评论中提到的那样,你逐渐习惯了这种模式:
#ifndef XXXXXXXXX
#define XXXXXXXXX

#endif
作为文件中的前两行和最后一行,您最终会注意到。如果你重复使用相同的名字,那就等到它回来了......     
有时,我将其用于“实现”头文件。警卫的实际命名方案可能有所不同。
#ifndef FOO_IMPL_H
#define FOO_IMPL_H

#ifndef FOO_H
#error Don't include this directly
#endif

// Ugly implementation of the stuff in foo.h, with an uncountable
// number of template and typename keywords

#endif 
    
在我看来,包括警卫应该包括警卫,仅此而已。如果你想要条件编译,我会定义其他东西。如果你在你的代码中throwing16ѭ,我认为人们会发现这很奇怪,因为
_H
通常表示一个包含守卫。 我能想到的一件事是检查文件是否已被包含(呃!),这样你就不必自己包含文件了。与前瞻性声明或
#pragma once
相比,我不确定这是否会加快编译速度 在main.cpp中:
#include "bar.h" // comment this line to see the difference
#include "foo.h"

int main()
{
    return 0;
}
在bar.h:
#ifndef BAR_H
#define BAR_H

class BarClass
{
};

#endif
在foo.h中:
#ifndef FOO_H
#define FOO_H

#if !defined(BAR_H)
#error bar h was not included // forgot how to do compiler warnings...
#include "bar.h" // we should include the file
#else
#error bar h was included // same thing, should be changed to warning
#endif

// do something with BarClass

#endif FOO_H
    
  我认为条件编译是一个很好的理由,在这种情况下命名它像FOO_H_INCLUDED会更清楚。 我只看到一个非常狭隘的用法,以避免在你只需要一个前向声明时包含一个标题,但是如果先前已经包含了标题,我想跳过前向声明。 然而,这不是今天编译C ++的瓶颈,而且总是具有前向声明或总是包含头部的额外混淆是不值得的。 即使你需要吨 - 我的意思是数百到数千行这些前向声明 - 所以它确实变得有价值,你最好使用一个专用的头,类似于< iosfwd>,而不是保持多个地方。     
对于重新调整用途:除非文件的全部内容都被ifndef / define / endif包围,否则
FOO_H
实际上不是文件包含保护,它只是保护文件的一部分。所以可能不应该在整个文件后面命名。递归包含相同的文件是可以出现这种情况的一种情况。 也就是说,我怀疑即使如此,它的定义应该是非常明显的(无论如何,更明显的是,你正在做的任何棘手的事情并不简单,包括防守)。在任何你看到模式ifndef FOO / define FOO,或者甚至只是fn / fOO /定义很多东西的情况下,一个简单的注释可以使FOO的意义明显,如果它还没有。 如果问题的任何部分是令牌
FOO_H
是否可能用于其他目的:我猜你是否有一个名为
uppercase.h
的文件使用
UPPERCASE_H
作为包含守卫,那么可以想象与某人的
rot13.h
冲突,包含
#define UPPERCASE_A ('N')
,愚蠢的例子,但是如果你在头文件中定义字母的属性,那么认为它们中的一些可能以
_H
结尾并不是荒谬的。 更现实的是,我的项目包含在不同目录中具有相同基本名称的包含文件。 因此,无论背景和再利用的问题,我都不会使用
FOO_H
作为包含守卫。     

要回复问题请先登录注册