#include in .h或.c/.cpp?

Lou*_*ise 105 c c++

当用C或C++编码时,我应该在哪里#include

callback.h:

#ifndef _CALLBACK_H_
#define _CALLBACK_H_

#include <sndfile.h>
#include "main.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data);
void on_button_cancel_clicked(GtkButton* button, struct user_data_s* data);

#endif
Run Code Online (Sandbox Code Playgroud)

callback.c:

#include <stdlib.h>
#include <math.h>

#include "config.h"

#include "callback.h"
#include "play.h"

void on_button_apply_clicked(GtkButton* button, struct user_data_s* data) {
  gint page;
  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(data->notebook));

  ...
Run Code Online (Sandbox Code Playgroud)

是否所有包括在.h或.c/.cpp中,或两者都像我在这里做的那样?

Rei*_*ica 144

把尽可能多的东西放在尽可能.c少的地方.h.在该包括.c当一个文件被编译只包括在内,但包括了.h必须由使用它的每一个文件被包括在内.

  • @ user9379这将阻止每个.c或.cpp文件包含多次.每个.c或.cpp文件通常都是单独构建的,这意味着将为您编译的每个.c或.cpp文件重新解析.h. (11认同)
  • 是的,但是顶部的`#ifndef _CALLBACK_H_`是否会阻止编译器多次处理它? (6认同)
  • 我认为在.h中尽可能少放置的主要原因是为了避免在某些情况下由于包含循环而导致的错误。示例:两个类的实现彼此需要,但不需要它们的声明。将两个include都放在`.cpp`中可以避免错误。 (2认同)
  • @Qu'est-cet'yont 这就是您*不能*将某些东西放入 .h 文件的原因。这个答案是关于为什么你应该投入更少的。 (2认同)

Joh*_*ode 47

您应该在另一个.h文件中包含标头的唯一时间是您需要访问该标头中的类型定义; 例如:

#ifndef MY_HEADER_H
#define MY_HEADER_H

#include <stdio.h>

void doStuffWith(FILE *f); // need the definition of FILE from stdio.h

#endif
Run Code Online (Sandbox Code Playgroud)

如果标题A依赖于标题B,例如上面的例子,那么标题A应该直接包含标题B. 千万不要尝试来订购包括.c文件来满足相关性(即,包括头A之前头B); 那是一堆胃灼热等待发生的事.我是认真的.我曾经多次参与过这部电影,并且总是以东京的火焰结束.

是的,这可能导致文件被多次包含,但如果它们具有适当的包含防护设置以防止多个声明/定义错误,那么额外的几秒构建时间就不值得担心.试图手动管理依赖项是一个痛苦的屁股.

当然,您不应该包含不需要的文件.

  • @olekstolar:在这种特殊情况下,这是行不通的,因为“FILE”是一个 typedef 名称,而不是类名。我们需要“stdio.h”中的“typedef xxx FILE;”定义。在其他情况下,是的,您可以转发声明不完整的类型,例如“struct foo;”或“class bar;”并且不包含头文件,但现在您增加了维护负担。您必须使前向声明与头文件中的内容保持同步 - 包含头文件更容易。不,“stdio.h”中的类型不太可能改变,但在用户定义的标头中,它们可以改变很多。 (2认同)

Par*_*ppa 9

尽可能多地包含在您的cpp中,并且只包含hpp中hpp文件所需的包含.我相信这将有助于加快编译速度,因为hpp文件的交叉引用会更少.

还要考虑在hpp文件中使用前向声明来进一步减少include依赖关系链.


Joh*_*web 5

如果我#include <callback.h>,我不想要#include很多其他头文件来编译我的代码.在callback.h你应该包括编译所需的一切.但仅此而已.

考虑在头文件中使用前向声明(例如class GtkButton;)是否足够,允许您减少#include头中的指令数(反过来,我的编译时间和复杂性).