头文件包含/前向声明
在我的 C++ 项目中,什么时候必须使用头文件的包含 (#include "myclass.h"
)?什么时候必须使用类的前向声明(class CMyClass;
)?
In my C++ project when do I have to use inclusion (#include "myclass.h"
) of header files? And when do I have to use forward declaration of the class (class CMyClass;
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
通常,首先尝试前向声明。这将减少编译时间等。如果不能编译,请使用
#include
。如果您需要执行以下任何操作,则必须使用#include:new
/delete
、复制等。(来自 @Mooing Duck 的 6,7,8,9)
它们可能更多,但我今天还没有戴上语言法帽子。
As a rule try the forward declaration first. This will reduce compile times etc. If that doesn't compile go for the
#include
. You have to go for the #include if you need to do any of the following:new
/delete
, copy etc.(6,7,8,9 from @Mooing Duck)
They're are probably more but I haven't got my language law hat on today.
转发声明有几个问题:
前向声明对其他人来说很难维护。例如,如果头文件包含:
而不是前向声明
其他人很容易找到类 Foo 的声明位置。通过前向声明,情况并非如此
明显的;当用户尝试打开时,某些 IDE(例如 Eclipse)可能会打开前向声明
变量的声明。
"Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
之类的错误,这样您就会知道在哪里查找相应的Foo.cpp
并识别包含它的库。如果您认为构建花费的时间太长,请尝试仅进行不带链接的编译。如果您的代码需要 10 秒来编译,10 分钟来链接,则问题与一些额外的包含无关。同样,如果您的头文件中包含太多内容,实际上导致了性能问题,那么您可能是时候将该文件的内容重构为多个较小的头文件了。
那么什么时候可以转发申报呢?如果您在与真实声明相同的头文件中执行此操作。
示例:
或
There are several problems to forward declaration:
Forward declarations are difficult for others to maintain. For instance, if a header file contains:
rather than the forward declaration
it is easy for others to find where the class Foo is declared. With forward declaration, it is not that
obvious; some IDEs like Eclipse may open the forward declaration when the user tries to open
the declaration of a variable.
"Could not find file MyProject/MyWidgets/MyFooWidgets/FooUtil/Foo.h"
since then you will know where to look for the correspondingFoo.cpp
and identify the library that contains it.If you think your build is taking too long, then try doing a compile only with no link. If your code takes 10 seconds to compile and 10 minutes to link, the problem has nothing to do with a few extra includes. Similarly, if your header file contains so much stuff in it that it is actually causing a performance problem then it is probably time for you to refactor the content of that file into multiple smaller header files.
So when is it OK to forward declare? If you do it in the same header file as the real declaration.
Example:
OR
如果您只需要指向类的指针,并且不需要有关该类的任何知识而不是其名称,则可以使用前向声明。
If you only need a pointer to the class and you don't need any knowledge about the class rather than its name, you can use the forward declaration.
作为初学者,当您需要使用它们包含的类型或函数时,您应该始终 #include 头文件 - 不要尝试通过前向声明来“优化”您的构建 - 这几乎没有必要,即使在大型项目中,只要项目架构良好。
唯一绝对需要前向声明的情况是在这样的情况下:
每个结构(或类)引用另一个结构(或类)的类型。在这种情况下,您需要 B 的前向声明来解决问题:
As a beginner, you should always #include header files when you need to use the types or functions they contain - do not try to "optimise" your build by forward declaring things - this is hardly ever necessary, even on large projects, provided the project is well architected.
The only time you absolutely need a forward declaration is in situations like this:
where each struct (or class) refers to the type of the other. In this case, you need a forward declaration of B to resolve the issue:
您应该努力尽量减少
#include
,这不仅是为了减少编译时间,也是为了帮助实现模块化和可测试性。正如 @ypnos 所说,当您只需要指针时,类转发非常出色。有关如何减少标头依赖性的一些实用技巧,请参阅本文。
You should strive towards minimizing your
#include
s both in order to reduce compilation times but also to help with modularity and testability. As @ypnos says, class forwards are excellent when you only need pointers.For some practical tips on how to reduce header dependencies, see e.g. this article.