C++ 自定义标题是否高于标准?

C++ 自定义标题是否高于标准?,c++,header,C++,Header,将自定义标题放在include部分比标准标题更高是否合理? 例如,在someclass.hpp中包含部分: #include "someclass.h" #include "global.h" #include <iostream> #include <string> #包括“someclass.h” #包括“global.h” #包括 #包括 这是最佳实践吗?如果是,利润是多少?将“widget.h”作为第一件事包含在widget.cpp中是相当常见的做法。这样做

将自定义标题放在
include
部分比标准标题更高是否合理? 例如,在
someclass.hpp
中包含部分:

#include "someclass.h"
#include "global.h"

#include <iostream>
#include <string>
#包括“someclass.h”
#包括“global.h”
#包括
#包括

这是最佳实践吗?如果是,利润是多少?

将“widget.h”作为第一件事包含在
widget.cpp
中是相当常见的做法。这样做的目的是确保
widget.h
是自包含的,即不会无意中依赖于其他头文件


除了这个之外,我认为这本质上是个人喜好的问题。

< P>你包含C++编译器的任何地方把它当作相同的

< P>。原因是如果你忘记在代码< > SOCCELASS中包含一个依赖的头。将收到未定义或未声明类型的警告/错误,等等。如果您首先包含其他标题,那么您可能掩盖了这一事实——假设包含的标题定义了所需的类型、函数等。例如:

#include "someclass.h"
int main() {
    SomeClass obj;
    obj.value = 1.0;
}
my_type.h:

// Supressed include guards, etc
typedef float my_type;
某些类别。h:

// Supressed include guards, etc
class SomeClass {
public:
    my_type value;
};
someclass.cpp:

#include "my_type.h" // Contains definition for my_type.
#include "someclass.h" // Will compile because my_type is defined.
...
这很好。但假设您想在程序中使用
SomeClass
。如果在包含
someclass.h
之前未包含
my\u type.h
,则会出现编译器错误,提示
my\u type
未定义。例如:

#include "someclass.h"
int main() {
    SomeClass obj;
    obj.value = 1.0;
}

从系统标题开始

如果报头之间没有依赖关系,那么这两种方式都是有效的,但由于编程本质上是通信,不是与计算机而是与其他人通信,因此使其具有逻辑性和易于理解是很重要的。我的意见是最好从系统头开始

这是我的第一个编程课程之一(我想是1984年),我们用Lisp编程,并被教导这样思考:从普通的Lisp语言开始,然后通过添加一些函数和数据类型,创建一种对应用程序更有用的新语言。例如,如果您添加日期和操作日期的能力,这种新语言可以称为带日期的Lisp。然后,您可以使用带有日期的Lisp创建一种具有日历功能的新语言,该语言可以称为带有日历的Lisp。就像洋葱上的一层

类似地,您可以将C视为一种“核心”语言,没有任何标题,然后您可以通过#include stdio.h将该语言扩展为一种新的、更大的具有I/O功能的语言。通过包含更多的标题,您向核心语言添加了越来越多的内容。(我知道术语“C语言”在其他上下文中指的是整个标准,包括所有的标准标题,但请注意这里。)每个新的包含标题创建一个新的、更大的语言,以及一个额外的洋葱层


现在,在我看来,标准标题显然应该是洋葱的内部部分,因此在自定义标题之前。您可以通过向C-with-I/O添加内容来创建C-with-monsters语言,但是创建C-with-I/O的人并不是从C-with-monsters开始的。

虽然这只是个人选择,但我更愿意首先包含标准标题。原因如下:

  • 任何一组
    #ifdef..#define
    都将被正确映射,而不是标准标题错误地解释它们。这适用于条件编译以及某些宏的值,同时编译标准头
  • 标准头文件中的任何更改/新函数都可能与您的函数冲突,并且编译器将在头文件中发出错误,这将很难解决
  • 所有必需的标准头都应该放在一个头中(最好是一些预编译的头),包括该头,然后包括自定义头。这将减少编译时间

在深入研究细节之前,需要进行两项重要观察:

  • 当您开发新的头/源对时,检查头是否是自包含的非常重要。要做到这一点,最简单的方法是将first包含在文件中
  • 最好不要在包含您不拥有的标题之前包含无关的内容,因为这可能会在宏冲突或函数过载的情况下产生奇怪的问题
  • 因此,答案取决于是否有单元测试


    一般的经验法则是包括从标准库开始的头,然后是第三方头(包括开源项目),然后是您自己的中间件、实用程序等。。。最后是这个库的本地头。它或多或少遵循依赖关系的顺序来遵守观察2


    我所看到的唯一例外是与当前源文件相对应的一个头文件,它将首先被包含以确保它是自包含的(观察1)。。。但这只适用于没有单元测试的情况,因为如果没有单元测试,那么单元测试源文件是检查这一点的好地方。

    为什么要问这个问题?你为什么认为这样更好?你想解决什么问题?我认为它实际上解决不了任何问题。我认为这是一个建议,但我不知道原因。我希望有人能更清楚地告诉我头文件的顺序其实并不重要。只有当一个头文件依赖于另一个头文件时才重要。原因只是表面的。假设头文件是独立的,任何顺序都将生成有效的程序。此外,我从未见过有人说“哦,看,这些
    #include
    的顺序是错误的”。@user1035174:“我认为这是推荐”从哪里来的?不一定。预处理器对它的处理是一样的,只是一个文本副本,但是如果将其包含在一个名称空间中,那么总体效果将非常不同。这是一个坏主意,通常情况下,为什么所有包含都位于顶部-使它们与其他任何内容分开。命名空间内部是另一种情况。范围以外