将函数放在头文件中的经验法则

Rules of thumb for putting functions in header files

本文关键字:经验法则 文件 函数      更新时间:2023-10-16

最近我开始将越来越多的函数放入头文件中,主要是为了方便。但我担心我可能做得过头了,我的标题充满了包含,我不确定这是否是一个好主意。

将函数移出或移入头文件的经验法则是什么?

如果你想知道,我说的是开发应用程序,而不是库。

编辑:

我想如果我从我的角度概述内联(自然)标头函数与实现函数的优缺点会很有帮助:

专业内联:

  • 更干净/简洁。
  • 无需重复签名。
  • 无需更改任何生成文件即可链接到新文件。
  • 即时引入模板参数的能力。

魂斗罗内联:

  • 增加编译时间(我不在乎那么多)
  • 许多包含在标题中(如果他们使用防护装置,应该不是一个大问题)

据此,将几乎所有函数都放在标头中似乎是一个好主意,我相信这与 STL 和 Boost 正在做的事情非常接近(尽管它们是库,而不是我的代码)。

我最不可违反的规则之一:头文件中只允许内联的函数体。其他任何事情都在链接阶段要求多个定义出现问题。

标题应主要用于声明而不是定义。我对该规则有例外(是灵活类型),但它们都不涉及非内联函数体。

我的经验法则是"除非必须,否则不在标题中"。至于方便,你觉得增加编译时间很方便吗?

有几个明显的技术方面 - 模板和内联函数必须在标题中 - 来自多个翻译单元的标头必须警惕一个定义规则 - 更直率地说,你想要一个血腥的好理由来考虑将一个离线函数实现放在标题中,我想不出我什至被诱惑过的任何时间。

因此,问题归结为:

    在标头中内联还是在实现文件中内联?

因素:

  • 说你正在设计应用程序级代码而不是库,所以你(目前)不必担心其他团队依赖于你的代码,也不必担心他们重新编译(而不是仅仅重新链接)的需要,通过保持实现不合时宜来最小化他们重新编译的需求。
    • 但是,如果你正在编写有潜力对其他团队有用的优秀代码,那么你可能会发现自己希望将实现保密。
  • 内联与外通常表示琐碎数据获取/设置函数的大约数量级开销...如果您有从性能关键代码重复调用的函数,那么您有理由更喜欢内联
  • 标头内实现(特别是如果与声明混合在一起)通常会混淆 API,但有时实际上会使代码更加自我记录
  • 本地化和删除冗余(组合声明/定义)肯定会消除拼写错误/错误的可能性,并且通常可以提高生产力

底线:如果你发现自己越来越多地这样做,那么它显然对你有用,没有特别的理由认为你会被烧伤。 留意潜在的问题,但不要根据一些假设的和不太可能实现的问题过度设计东西。

一个好的编码标准会告诉你在源(cpp)文件中实现方法和函数。

如果您愿意,可以在标头中实现模板和内联函数。

既然这已被标记为C++,为什么不将它们分成逻辑class es?

通常我在头文件中有一个class声明,它在相应的源文件中定义。

我使用的两个规则是

1) 如果是内联函数

2)如果是模板函数。

首先,模板函数必须放在标题中。

此外,具有空主体的函数(例如默认构造函数或默认但虚拟析构函数)可以放在标头中。

我从不使用inline因为编译器不能保证这一点。