我应该把C++ #include包含在哪里?在标题或实现中?

Cri*_*ter 2 c++ include

假设我在CameraVision.cpp文件中有一个名为CameraVision的类.

该类的构造函数接受一个向量IplImage*(IplImage是一个C结构,表示OpenCV中的图像).我需要在CameraVision.hpp或CameraVision.cpp中#include opencv.h.

哪个更好?为什么?(#在CameraVision.hpp或CameraVision.cpp中包含这些?)

另外,我应该在哪里#includeSTL <vector>,<iostream>等等?

假设CameraVision.cpp的客户端也使用<vector><iostream>.客户显然#include CameraVision.hpp(因为他是CameraVision的客户).CameraVision.cpp的客户是否也应该#include,<iostream>等等,如果他们已经#include进入了CameraVision.hpp?客户如何知道这一点?

Dev*_*lar 8

这里的规则是:限制范围.如果你只能在实现文件中包含include(例如通过使用前向声明,包括<iosfwd>等),那么就这样做.在公共接口中,即客户端将包含的标头用于使用您的库,请考虑使用PIMPL模式隐藏任何实现细节.

好处:

1)代码的清晰度.基本上,当某人正在查看头文件时,他正在寻找关于你的课程内容的一些想法.包含的每个标头都会在标题中添加"范围":要考虑的其他标头,更多标识符,更多结构.在非常糟糕的代码中,每个标题包含更多标题,如果不了解整个库,就无法真正理解一个类.尝试将这种依赖性保持在最低限度使得更容易理解隔离的类的接口.("不要打扰IplImage实际上什么,在内部,或者它能做什么 - 此时我们只需要指向它的指针").

2)编译时间.由于编译器必须执行与1)中所述相同类型的查找,因此头文件中包含的内容越多,编译源的时间就越长.在极端情况下,编译器必须包含每个翻译单元的所有头文件.虽然结果编译时间对于一次性编译可能是可接受的,但这也意味着必须在对标题进行任何更改后重新编译.在严格的编辑 - 编译 - 测试 - 编辑周期中,这可以快速加起来达到不可接受的水平.

编辑:不完全是主题,但是当我们在它时,请不要using在头文件中使用,因为它与限制范围相反...


Ale*_*lov 5

为了避免额外的包含,在所有情况下都应该在实现 (.cpp) 文件中使用 #include,除非您正在导入的名称用于模块导出的原型或声明中。

例如:

foo.h:

#ifndef _FOOBAR_H_
#define _FOOBAR_H_

#include <vector>

void foo();
std::vector<int> bar();

#endif // _FOOBAR_H_
Run Code Online (Sandbox Code Playgroud)

foo.cpp:

#include "foo.h"
#include <iostream>

void foo() {
    std::cout << "Foo";
}

std::vector<int> bar() {
    int b[3] = {1, 2, 3};
    return std::vector<int>(b, b+3);
}
Run Code Online (Sandbox Code Playgroud)