繁体   English   中英

自定义标题高于标准?

[英]Custom headers higher than standard?

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

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

#include <iostream>
#include <string>

这是最佳做法吗? 如果是,它的利润是多少?

这是相当常见的做法是#include "widget.h" 作为第一件事情 widget.cpp 这样做可以确保widget.h是自包含的,即不会无意中依赖于其他头文件。

除此之外,我认为这基本上是个人偏好的问题。

原因是如果你忘记在someclass.h包含一个依赖的头,那么无论实现文件包含它作为第一个头,都会得到一个未定义或未声明类型的警告/错误,以及诸如此类的东西。 如果首先包含其他标题,那么您可能会掩盖这一事实 - 假设包含的标题定义了所需的类型,函数等。示例:

my_type.h:

// Supressed include guards, etc
typedef float my_type;

someclass.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 如果不包括my_type.h包括前someclass.h ,你会得到一个编译器错误说my_type是不确定的。 例:

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

在深入研究具体细节之前,有两个重要的观察结果:

  1. 在开发新的标头/源对时,检查标头是否为自包含很重要。 要做到这一点,最简单的方法是首先包含在文件中。
  2. 在包含您不拥有的标头之前,最好不要包含无关的内容,因为这可能会在宏冲突或函数过载的情况下产生奇怪的问题。

因此,答案取决于您是否进行单元测试。

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

我看到的唯一例外是当前源文件对应的一个标题,首先将其包含在内以确保它是自包含的( 观察1 )...但这仅在您没有单元测试时才有效,如果你这样做,那么单元测试源文件是一个检查这个的好地方。

从系统标头开始。

如果标题之间没有依赖关系,则两种方式都有效,但由于编程本质上是通信,而不是计算机而是与其他人,因此使其合乎逻辑且易于理解是很重要的。 我的观点是,最好从系统头开始。

我的第一个编程课程(1984年,我认为)是我的第一个编程课程,我们用Lisp编程,并教导他们这样思考:你从普通的Lisp语言开始,然后你创建一个更有用的新语言通过添加一些函数和数据类型为您的应用程序。 例如,如果您添加日期和操作日期的功能,则可以将此新语言称为Lisp-with-dates。 然后你可以使用Lisp-with-dates来创建一个具有日历功能的新语言,可以称之为Lisp-with-calendars。 像洋葱中的层。

类似地,您可以将C视为具有“核心”语言,而不使用任何标题,然后您可以通过#including stdio.h将此语言扩展为具有I / O功能的新的更大语言。 您可以通过#including more headers向核心语言添加越来越多的东西。 (我知道其他上下文中的术语“C语言”是指整个标准,带有所有标准标题,但在这里请耐心等待。)每个新的#included标题创建一个新的,更大的语言,以及一个额外的层洋葱。

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

虽然这只是个人选择,但我希望首先包含标准标题。 几个理由:

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

你包含c ++编译器的任何地方都将它视为相同

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM