提问人:Luchian Grigore 提问时间:10/4/2012 最后编辑:Luchian Grigore 更新时间:10/4/2012 访问量:566
转发声明一切
Forward declare everything
问:
事实:(类类型的)正向声明比包含声明更受欢迎。
在标头中转发声明所有内容并包含该标头是否有缺点?(我猜编译时间应该不会增加很多)
在大型代码库中,正向声明可能会占用大量的屏幕空间,用单个包含替换它们会很酷 - 但是,为每个带有正向声明的标头设置一个正向声明标头是没有意义的。
以前有没有人做过这个或见过这个?
答:
我通常在我的项目中这样做。但我在 .例如:,等等。这在重新编译大量(因为在标头中使用 includes)和手动编写前向声明之间提供了很好的平衡modules
gui
core
我认为在不走极端的情况下,转发包含几乎没有任何缺点。
我个人不会在乎屏幕空间。它肯定胜过将构建时间乘以 2 到 5 到 10。我们曾经的构建时间超过 2 小时......一些额外的转发包含可以消除相同的文件被击中数千次。
无论如何,你不能总是对所有事情都使用正向声明。如果你要对某些东西进行子类化,那么你必须有类定义,这可能意味着包含。没关系。
要删除依赖项,您可以做的一件事是在头文件中取消内联代码。确保将接口向上推送,并将实现向下推送(参见 Sutter 和 Alexandrescu 的 C++ 编码标准)。这意味着,如果可能的话,你的公共 API 最好是抽象接口。如果可以这样做,则可以将需要包含或转发声明的金额降至最低。
哦,也不要把数百个函数和类放在一个头文件中,所以它有 8000 行长。没有人可以阅读/理解此类文件。
评论
使用正向声明而不是包含的主要好处之一是,您不需要在更改头文件时重新编译尽可能多的源文件,因为该头文件只会包含在实际需要的地方。
您的方法可能会减少这种好处,在某些情况下甚至会使情况变得更糟:每次在某处添加或删除类时,都需要更改包含正向声明的全局头文件。然后,您需要重新编译代码库中的每个源文件,包括那些不使用添加类的文件。
不过,由于类可能不会太频繁地添加,也许这并不是一个太糟糕的权衡。
评论
上一个:虚拟继承和同名成员
评论
"however, it doesn't make sense to have a forward-declaration header for each header"
->为什么你认为这没有意义?在我看来,这是最干净的方法:如果我需要 的完整定义,那么我包括 ;如果我只需要它的声明,那么我包括.这样,正确声明类是包含的库的责任,允许我忽略实现细节(有多少人试图转发声明并失败..?事实上,这种方法在一些 Boost 库中使用。Foo
Foo.hpp
Foo_fwd.hpp
Foo
std::vector