最佳实践:C++头文件包含

3

我目前正在学习C++,我认为我已经理解了关于包含头文件的大部分知识...来自其他编程语言,在那里这根本不是必需的,我经常有一种感觉'这是错的'或者应该有'更简单的方法':

  1. 我发现每个类都要包括(例如)"vector"非常烦人。有更好的方法吗?

  2. 我有很多核心功能(也在它自己的命名空间中)有很多类,很少改变。虽然我并不需要每个类中的所有功能,但只需有一个单一的头文件,包含它并完成它会非常好…最好的方法是什么?

  3. 在预编译头文件中包含头文件是否是不好的实践?如果是的话,为什么?


3
很抱歉,这并不是该网站应该回答的问题。我建议你在搜索引擎上搜索相关主题,并阅读一些有关标题管理的好的技巧文章。 - Dariusz
1
@Dariusz:我不同意。虽然这是一个普遍性问题,但它表述得很清楚,也没有采用“教我X”的形式。如果提问者能够撰写一篇不太笼统或广泛的、表述得当的问题,那么询问一般性建议是可以的。我认为cboe在这方面做得很好。 - John Dibling
注意:clang团队的Douglas Gregor正在开发模块实现,作为未来标准化的先驱工作。虽然已经晚了很久,但我们可以希望有一天C++终将获得一个适当的模块系统,我们可以摆脱那些头文件... - Matthieu M.
抱歉如果我误用了SO,我认为这些问题已经足够具体了! - cboe
目前你有三个问题,它们都非常模糊。当然可以提出你想问的问题,但请尝试将其缩减为一次只提出一个问题,并尽量要求更具体的内容。 - Sam I am says Reinstate Monica
4个回答

3
您感觉在需要时使用#include并将所需的内容包含进去是“错误”的,这种感觉可能来自于您从其他语言中获得的偏见,在这些语言中,这不是必要的。
在C++中,推动许多范例的哲学是“只为所用或所需付费”。其中一种体现方式是需要对编写的组件所需的所有头文件进行#include。没有什么会被自动#include
有一些常用的快捷方式可以使这个过程变得更简单。其中之一是使用所谓的预编译头文件或全局头文件,它们本身#include了在整个项目中全局使用的所有底层内容。您可以编写此类标题,并在任何需要它的文件中#include该标题,而不是包含几十个独立的文件。
“只为所用付费”哲学的好处之一在编译时实现。如果您仅需要三个小的头文件,则仅包含这三个文件,而不是数十个不需要的冗杂文件,将加速编译时间。

2
  1. 一般情况下不行,但有例外。更进一步说,你不应该依赖于包含在被包含的头文件中的内容,但有时候可以这样做。例如,在派生类中,你几乎可以依赖于基类的包含。
  2. 创建自己的include,只需包含一堆其他的includes。但要小心使用。
  3. 对于很少更改的大型includes来说,这是一个好的实践。这在posix系统上也不是很常见的做法。

1

1.我发现每次想使用向量时都要包含(例如)<vector>,这让我非常烦恼。有没有更好的方法?

想象一下其他人使用你的代码时(其中可能包括你未来的自己),由于缺少<vector>头文件而导致编译错误是多么令人恼火。只需写一次,便可多次使用。

2.我有很多核心功能(也在其单独的命名空间中)的代码,其中有相当多的类不经常更改。虽然我不需要在每个类中都使用所有功能,但只需有一个单一的头文件,包含它并完成它将会非常好...最好的方法是什么?

你可以通过让IDE自动将其包含为预编译头文件来加速操作。但是出于正确性和可移植性的考虑,你不应该依赖它,始终让每个头文件都能够独立编译。参见Alexandrescu & Sutter's编码规范中的第23项。像CMake这样的构建系统甚至有测试此功能的宏。

3.在预编译头文件中包含头文件是否是一种不好的实践?如果是,为什么?

你可以这样做,但最好让IDE来完成以获得更好的可移植性。并且那些头文件最好是稳定的(例如标准库或Boost),但永远不要包含你自己项目的头文件。

非常感谢您提供的所有答案,帮了我大忙。我发现这个是最清晰明了的答案。 - cboe

0
创建一个common.h头文件。在其中包含所有必要的头文件,并将其包含在所有其他头文件中(我不知道其他人怎么做,但我们在我的项目中遵循这个方法)。
最好的做法是包含预编译头文件(只需包含很少更改的头文件)。但是我只在Windows C++中看到过预编译头文件(stdafx.h),在其他地方没有看到过。

Xcode也支持在.pch文件中使用它。 - cboe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接