假设我在CameraVision.cpp文件中有一个名为CameraVision的类。
此类的构造函数采用IplImage*
vector (IplImage是一种C结构,表示OpenCV中的图像)。我需要在CameraVision.hpp或CameraVision.cpp中#include opencv.h。
哪个更好?为什么? (#将它们包括在CameraVision.hpp或CameraVision.cpp中吗?)
另外,我应该在哪里#include
STL <vector>
,<iostream>
等?
假设CameraVision.cpp的客户端也使用<vector>
和<iostream>
。客户显然会使用#include CameraVision.hpp
(因为他是CameraVision的客户)。 CameraVision.cpp的客户端是否还应该#include,<iostream>
等(如果已经在#include
中添加了CameraVision.hpp
)?客户将如何知道这一点?
最佳答案
这里的规则是:限制范围。如果您只能将include包含在实现文件中(例如通过使用前向声明,包括<iosfwd>
等),那么可以这样做。在公共(public)接口(interface)中,即,您的客户端将包含的 header 以使用您所制作的库,请考虑使用PIMPL模式隐藏任何实现细节。
好处:
1)代码清晰。基本上,当某人正在查看头文件时,他正在寻找有关类的内容的一些想法。包含的每个 header 都会在 header 中添加“作用域”:要考虑的其他 header ,更多的标识符,更多的构造。在非常糟糕的代码中,每个 header 都包含更多的 header ,并且如果不了解整个库就无法真正理解一个类。尝试将此类依赖关系保持在最低限度,可以更轻松地单独了解类的接口(interface)。 (“不要打扰IplImage
实际上是什么,内部或它可以做什么-在这一点上,我们需要的只是指向它的指针”)。
2)编译时间。由于编译器必须执行与1)中所述的相同类型的查找,因此头文件中包含的内容越多,则编译源代码所花费的时间就越长。在极端情况下,编译器必须为每个翻译单元包括所有头文件。尽管最终的编译时间对于一次编译来说是可以接受的,但这也意味着在对 header 进行任何更改后,都必须重新完成编译时间。在严格的编辑-编译-测试-编辑周期中,这可能很快加到 Not Acceptable 水平。
编辑:不完全是主题,但是在我们讨论的时候,请不要在头文件中使用using
,因为这与限制范围相反。