cli*_*ith 5 c++ static-libraries
我有一个用 C++ 构建的静态库。我把它分成了许多头文件和源文件。我想知道将库的客户端可能需要的所有头文件包含在一个头文件中是否更好,而这些头文件又可以包含在他们的源代码中,还是只包含他们需要的头文件?这会导致代码不必要的臃肿吗?我不确定未被使用的类或函数是否仍会被编译到他们的产品中。
谢谢你的帮助。
请记住,您编译的每个源文件都涉及编译器的独立调用。每次调用时,编译器都必须读取每个包含的头文件,对其进行解析,并构建符号表。
当您在许多源文件中使用这些“包含世界”头文件之一时,它会显着影响您的构建时间。
有一些方法可以缓解这种情况;例如,微软有一个预编译头功能,它本质上保存了符号表以供后续编译使用。
但还有另一个考虑因素。如果我要使用您的 WhizzoString 类,那么我不必安装 SOAP、OpenGL 等标头。事实上,我宁愿 WhizzoString.h 只包含属于公共接口一部分的类型和符号的标头(即,我作为类的用户将需要的东西)。
您应该尽可能尝试将包含内容从 WhizzoString.h 转移到 WhizzoString.cpp:
好的:
// Only include the stuff needed for this class
#include "foo.h" // Foo class
#include "bar.h" // Bar class
public class WhizzoString
{
private Foo m_Foo;
private Bar * m_pBar;
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
更好的:
// Only include the stuff needed by the users of this class
#include "foo.h" // Foo class
class Bar; // Forward declaration
public class WhizzoString
{
private Foo m_Foo;
private Bar * m_pBar;
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
如果您的类的用户从不需要创建或使用 Bar 类型,并且该类不包含 Bar 的任何实例,那么仅在头文件中提供 Bar 的前向声明可能就足够了(WhizzoString.cpp 将具有#include "bar.h")。这意味着包括 WhizzoString.h 在内的任何人都可以避免包括 Bar.h 及其包含的所有内容。
一般来说,当链接最终的可执行文件时,只会合并程序实际使用的符号和函数。您只需为您使用的内容付费。至少 GCC 工具链似乎对我来说是这样工作的。我不能代表所有工具链。
如果客户端始终必须包含同一组头文件,那么可以提供包含其他头文件的“方便”头文件。这是开源库中的常见做法。如果您决定提供一个方便的标头,那么客户端也可以选择包含具体需要的内容。
为了减少大型项目的编译时间,通常的做法是包含尽可能少的标头来进行单元编译。