代码之家  ›  专栏  ›  技术社区  ›  xyzzyrz

如何在头库中定义(非方法)函数

  •  4
  • xyzzyrz  · 技术社区  · 16 年前

    在编写头库时(如 Boost ,可以定义自由浮动(非方法)函数而不(1)使生成的二进制文件膨胀,(2)引起“未使用”警告吗?

    当我在一个头文件中定义一个函数,该函数由多个源文件包含,而这些源文件又链接到同一个二进制文件中时,链接器会抱怨重新定义。解决这一问题的一种方法是使函数保持静态,但这会复制每个翻译单元中的代码(顺便说一句,链接器能否安全地将这些代码取消复制?)。此外,这会触发编译器关于未使用的函数的警告。

    我试图寻找一个在Boost中自由浮动函数的例子,但是我找不到。在类(或模板)中包含所有内容的技巧是什么?

    5 回复  |  直到 16 年前
        1
  •  12
  •   David Joyner    16 年前

    如果您真的想定义函数(而不是声明它),您需要使用 inline 以防止链接器错误。

    否则,您可以在头文件中声明该函数,并在源文件中单独提供其实现。

        2
  •  8
  •   GManNickG    16 年前

    您可以使用 inline 关键词:

    inline void wont_give_linker_errors(void)
    {
        // ...
    }
    
        3
  •  2
  •   AnT stands with Russia    16 年前

    呃。。。你问题的答案很简单 不要 . 你只是 不要 在头文件中定义函数,除非它们是内联的。

    “static”函数也可以在头文件中定义,但它只对非常特殊的特殊用途有用。使用“静态”来解决一个多定义问题完全是胡说八道。

    同样,头文件用于非定义函数声明。你到底为什么要 定义 那里的功能?

    你说你在写“标题库”。什么是“标题库”?请注意,boost在头文件中定义了它的“函数”,因为它们的“函数”实际上不是函数,而是 函数模板 . 函数模板必须在头文件中定义(几乎是这样)。如果不是这样的话,Boost不会像在头文件中定义任何东西那样做奇怪的事情。

        4
  •  1
  •   sbi    16 年前

    除了前面提到的 inline ,对于大多数编译器,必须在头中定义模板(并且允许使用所有编译器)。因为Boost主要是模板,这就解释了为什么它几乎都是头文件。

        5
  •  -1
  •   Troubadour    16 年前

    有人建议 inline 但这违反了问题的第一部分,即当函数每次调用时将完整定义插入代码时,它会使代码膨胀。因此,你的总体问题的答案是“不”。

    如果你把它们标为 static 然后,它们仍然在每个源文件中定义,正如您正确指出的那样,但仅限于 一旦 所以这是一个比 内联 如果代码大小是 只有 问题。我不知道链接器是否可以,或者被允许,发现重复的内容并合并它们。我怀疑不是。

    编辑 以下内容:

    只是为了澄清我是否支持使用 静止的 和/或在头文件中定义函数,一般来说,我不这么认为。这只是对标记函数之间的差异的技术响应。 内联的 静止的 在头文件中定义。再也没有了。