C++ 使用C+的最佳实践+;标头档

C++ 使用C+的最佳实践+;标头档,c++,header-files,C++,Header Files,我对头文件的用法有以下疑问 1-包括在评论后放置的防护装置 /* Copyright Note and licence information (multiple lines) */ #ifndef FOO_H #define FOO_H // Header file contents #endif #ifndef FOO_H #define FOO_H namespace FooNameSpace{ // Header file contents } #endif Herb Sut

我对头文件的用法有以下疑问

1-包括在评论后放置的防护装置

/* Copyright Note and licence information (multiple lines) */
#ifndef FOO_H
#define FOO_H
// Header file contents
#endif
#ifndef FOO_H
#define FOO_H
namespace FooNameSpace{
    // Header file contents
}
#endif
Herb Sutter在他的《C++编码标准》一书中说,像上面这样的代码是有问题的。他说“#ifndef”语句应该出现在头文件的第一行。我觉得这没有说服力。头文件中有你们这些家伙/女孩吗

2-在头文件中使用名称空间

/* Copyright Note and licence information (multiple lines) */
#ifndef FOO_H
#define FOO_H
// Header file contents
#endif
#ifndef FOO_H
#define FOO_H
namespace FooNameSpace{
    // Header file contents
}
#endif
上述代码是否使用了正确的实践?我的意思是,你在头文件中使用名称空间吗?我知道为什么在头文件中导入名称空间是毫无意义的,但是像上面这样的声明呢

如果上面的方法是正确的,那么如何对另一个命名空间中的类进行“前向声明”?是这样的吗

#ifndef FOO_H
#define FOO_H
namespace AnotherNameSpace{
    class AnotherFoo; // forward declaration
}

namespace FooNameSpace{
    // Use AnotherFoo here
}
#endif
“转发声明”是避免“循环依赖”的唯一方法,对吗

  • include卫士和注释的顺序纯粹是风格的问题——它不会对编译速度产生任何可测量的影响

  • 名称空间绝对应该在头文件中用于声明函数、类、全局变量等。不应该在头文件中使用
    语句——不可能在包含它的源文件中使用某些内容,也不应该强制includers向全局范围添加额外内容。如果需要在标题中使用其他名称空间中的内容,请完全限定每个名称。有时候会很痛苦,但这确实是正确的做法

  • 示例:

    // WRONG!
    using namespace std;
    class MyClass
    {
        string stringVar;
    };
    
    // RIGHT
    class MyClass
    {
        std::string stringVar;
    };
    
    至于其他名称空间中类的前向声明,您已经完全正确了。只要记住,当您在标题中引用它时,总是将
    AnotherFoo
    限定为
    AnotherNameSpace::AnotherFoo
    。事实上,前向声明是打破循环依赖关系的唯一方法。

    关于#1,我不知道有任何支持或反对的具体论据。许多公司都有这样一个政策,即版权声明必须是文件中的第一项,然后才是其他任何内容或任何有意义的代码(可能假设您在吸收任何代码之前先阅读版权)。为此#IFNDEF已经是代码。从可用性的角度来看,把版权放在第一位是有意义的,因为眼睛忽略了它们。然而,在我看来,任何描述模块的内容都应该放在“ifndef”之后。

    1)因为评论实际上没有任何作用,我怀疑它是否重要。但是从技术上讲,#包括复制和粘贴,因此将注释放在标题保护之外可能意味着预处理器需要做更多的工作。我不知道大多数编译器是否足够聪明,可以为此进行优化(例如,如果它们在预处理器步骤之前剥离注释),但在到达成千上万个头文件之前,您可能不会注意到

    2) 没错。如果您想将一个类放在一个名称空间中,并且该类将在头文件中声明,那么它应该在名称空间中声明,因此应该在头文件中声明。是的,这就是你准确的申报方式。是的,它是避免循环依赖的主要工具(您也可以更改您的设计,但原则上,如果所讨论的两个类仅通过引用或指针相互引用,而不调用任何方法,那么循环性没有错)

  • 我听说你有意见 在防护罩可能导致 某些编译器可能会错过 优化。如果警卫是 首先,编译器可能会 认得这个成语,甚至不认得 费心打开收割台以便继续 后续包括。我自己 代码,注释通常位于 包括警卫。我从来没有 费心测试,看看这是否有问题 有没有影响。我可能永远不会(但如果其他人这样做,我会对结果感兴趣)

  • 当然,标题应该包含 名称空间-否则什么都没有 有用的东西可能就在一个 命名空间。然而,正如你所说 如前所述,不应使用标题 “导入”(因为缺少更好的词) 将名称空间转换为编译单元 使用“
    using
    ”指令

  • 我不认为添加评论对性能有任何影响,正如Adam对这篇文章的回答所指出的那样

  • 我在头文件中使用了自己的名称空间,如果您定义自己的字符串类,那么它将与std名称空间字符串类冲突

  • 在源文件中,使用“Using”一点也不错,但在头文件中,它是非常错误的。