我能(不能)在 .cpp 文件中包含什么?

What am I able to (not) include in a .cpp file?

这个问题很奇怪。 假设我有一个名为 idiot.cpp 的文件,它以:

开头
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>
#include "idiot.h"

我有一个 header 文件,idiot.h。首先,在idiot.h中,我是否也必须插入

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>

或者我没有? 其次,如果我有另一个使用 idiot.h 的源文件,例如 "bonito.cpp,",我应该只 #include "idiot.h",还是应该再次粘贴代码片段? 如果没有,有没有什么办法可以缩短它,这样我就不会在每个文件中包含大约 20 headers? (假设) 抱歉,如果这是一个非常愚蠢的问题,但我不会经常使用很多 header。

idiot.cpp 不需要包含任何由 idiot.h 间接包含的内容就可以编译。

更有趣的案例:bonito.cpp #includes idiot.hidiot.h 包括 x.h。如果 idiot.h x.h 的内容用于私有或匿名命名空间代码 - 并且 bonito.cpp 也想使用 x.h 中的内容,那么 bonito.cpp 应该直接(冗余地)包含 x.h

理由很简单:idiot.h 不能从 public/protected 接口中删除某些东西而不冒破坏客户端代码的风险,所以如果发生这种情况,那么客户端必须期望处理它 - 可能还包括一个额外的 header。但是,idiot.hidiot.cpp 的维护者应该可以自由更改 idiot.h 中的私有或匿名命名空间内容,而不会冒破坏客户端代码的风险,包括包含哪些 headers 以支持那个私人密码。

因此,包含在完成时是多余的,但这样做是希望随着 idiot.h 的发展它可能不再是多余的。

此 best-practice 模型不会自动执行 - 您必须了解它的工作方式并积极为该模型编写代码。

例子

如果 idiot.h 包含...

#include <string>
#include <vector>
...
class X {
    void add(const std::string&);
  private:
    std::vector<std::string> v_;
};

...那么bonito.cpp可以合理使用std::string而不包含<string>,但是如果需要std::vector<>应该包含<vector>本身。