繁体   English   中英

您是否应该在头文件中包含源代码?

[英]Should you include source code in a header file?

我正在将一些源代码移植到linux系统上,并且正如预期的那样,某些东西已损坏。 现在对我抛出错误的一件事是,某人拥有一个都使用fclose()的.h和.cpp文件

编译器抱怨在头文件中未声明fclose()。

这是头文件中的函数声明:

void closeFile() { if (fp) fclose(fp); }

现在,我认为这是不好的风格,但是-他们是如何使它工作的呢? 他们的编译器版本是否允许这种行为?

我应该通过在标头中包含stdio来解决此问题,还是将整个内容移至cpp?

这不是不好的风格,您可以将源代码放入头文件中,有时甚至会被迫这样做:

  • 定义模板类/功能时。

  • 定义内联函数时。

无论如何,您都不应在头文件中放置一个免费的(在类范围之外定义的)非内联函数,因为只要源文件中包含此类头文件,该内联函数都将被编译(这将为您提供链接错误)。

如果您收到未声明fclose的错误,则可能是因为未在该代码段之前声明cstdio (或stdio.h )。 在头文件的开头放置#include <cstdio>

仅添加关于其他答案的两件事,请记住内联不是顺序,更多地是猜测编译器应该做什么,除非您强制内联。 大多数编译器可以决定何时内联函数,即使您没有内联声明它也是如此。 这不是必须的 ,这是应该的

有时您确实需要在标头中包含此类函数/结构/类定义,而有时它们并不琐碎或那么简单。 但是这些定义通常是您需要的一些辅助功能,您只是不想将它们包括在主文件中,只是为了更好地组织事情。

我见过的关于这种做法的最好的例子(好吧,我没看到太多)是游戏源代码(这是我的主要兴趣:))。

顺便说一句,我通常不对头文件(结构和枚举除外)放置任何声明,而是将它们放置在单独的文件中,除非:

  • 仅需要进行一些声明/辅助功能。 要么
  • 这些声明是我将在另一个contex(在同一项目中)使用的函数,我只是认为最好将它们视为独立的“辅助库”(在相同上下文中)。

希望它能有所帮助。

请记住,头文件不是由它们自己编译的(通常)。 它们被#include d到源文件中,并且解析头文件时可用的定义是有问题的头文件上方的源文件中包含的内容。

无论头文件是否是执行一个合适的位置closeFile()你的头文件应该#include它需要在自身上的一切。 因此,在头文件的顶部添加#include <stdio.h>

(请注意,如果这是要编译到Linux内核本身的代码,则可能需要与stdio.h不同的标头。通常,应用程序级标头不适合在内核源代码中使用。)

如果未在此标头中或在使用此标头的地方之前未包含stdio.h ,则fclose()将是未定义的。 这就是为什么会发生错误。

我个人认为允许在头文件中的代码没有任何问题,但是,如果是这样,并且您使用的是C99,则应声明它

inline void closeFile() { if (fp) fclose(fp); }

这意味着多个已编译对象将没有closeFile()符号(由于inline ),并且inline向编译器暗示不应将此作为函数调用而应代之以可能需要速度的inline

标头由文本替换包括(即标头的全部内容替换为#include声明)。 因此,如果只有一个.cpp文件包含此特定标头,则等效于在.cpp文件中定义功能。 我认为这就是它在链接时起作用的原因。

C标准仅定义了必须包含的标头以具有可用的功能,但不禁止系统标头相互包含。 因此,在某些系统上, stdio.h标头可能被另一个标头隐式包含(因此编译器未报告任何错误)。

就我个人而言,我会将此类代码移至.cpp文件,因为它不那么脆弱(标头可以包含在多个.cpp文件中,该标头不需要先前包含stdio.h标头),并且可以如果必须更改实现,则可以更快地重新编译(添加日志记录或适当的错误处理,因为关闭文件可能会失败)。

暂无
暂无

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

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