仅限标头库和多个定义错误

时间:2010-10-19 22:14:36

标签: c++ header multiple-definition-error

我想编写一个要使用的库,您只需要包含一个头文件。但是,如果您有多个源文件并在两者中都包含标头,则会出现多个定义错误,因为该标头都是在标头中声明和定义的。我认为在Boost中我看过只有头文件的库。他们是怎么做到的?

4 个答案:

答案 0 :(得分:27)

声明你的函数inline,并将它们放在命名空间中,这样就不会发生冲突:

namespace fancy_schmancy
{
  inline void my_fn()
  {
    // magic happens
  }
};

答案 1 :(得分:5)

Boost主要仅仅是标题的主要原因是因为它主要是面向模板的。模板通常从一个定义规则获得传递。事实上,为了有效地使用模板,您必须在使用该模板的任何翻译单元中显示该定义。

围绕一个定义规则(ODR)的另一种方法是使用inline函数。实际上,获得ODR的免费通行证是inline真正做到的 - 它可能内联函数的事实实际上更多是一个可选的副作用。

最终选项(但可能不太好)是使您的函数保持静态。如果链接器无法确定所有这些函数实例是否真的相同,则可能导致代码膨胀。但我提到它是完整的。请注意,编译器通常会内联static函数,即使它们未标记为inline

答案 2 :(得分:2)

Boost使用了只有头文件库,因为像STL一样,它主要是使用类和函数模板构建的,它们几乎总是只有头文件。

如果你不编写模板,我会避免在你的头文件中包含代码 - 这比它的价值更麻烦。使它成为一个普通的旧静态库。

答案 3 :(得分:1)

有许多真正的仅限标头的Boost库,但它们往往非常简单(和/或只有模板)。较大的库通过一些技巧实现相同的效果:它们具有“自动链接”(您将看到这个术语使用here)。它们在头文件中基本上有一堆预处理程序指令,用于为您的平台找出适当的lib文件,并使用#pragma指示链接器将其链接。因此您不必显式链接它,但是它仍然存在联系。