当前位置:   article > 正文

C++头文件里的内联函数加不加static有什么区别?_头文件里写static函数

头文件里写static函数

static 是 static, inline 是 inline

自由函数(就是不隶属 class/struct的函数),加 static ,这来自 C 语言的 “封装”:即让这个函数只在当前 源文件 (即需独立编译的文件: .c 或 cpp 之类,不包括 头文件)之内可见。此时它和extern 这个修饰相对应,当然,因为自由函数默认是 extern,可以不写。例子:

假设有个 a.cpp ,里面有个 static 的 foo 函数:

  1. // a.cpp
  2. static void foo () {}

然后,现在你想在别一个源文件,比如 main.cpp 里再使用它,哪怕你特意再声明它是 extern ,在链接时,也会报找不到 foo 的定义:

为了帮助大家更好地入门并深入掌握C++,我们精心准备了一系列丰富的学习资源包,包括但不限于基础语法教程、实战项目案例、核心概念解析以及进阶技巧指导等。

您只扫码上方二维码,即可免费获取这份专属的学习礼包。我们的教程覆盖了C++语言的各个方面,旨在让您在理论学习与实践操作中不断进步,提升编程技能。

同时,我们也鼓励您在学习过程中遇到任何问题时积极提问,我们会尽全力提供解答和帮助。期待您在C++编程的道路上越走越远,早日成为一位优秀的C++开发者

  1. // main.cpp
  2. int main(){
  3. extern void foo();// 特患声明:在“外部/extern”某个地方有一个 foo
  4. foo();// 编译通过,链接失败
  5. }

 嗯,就是这样: 我们在使用 foo 之前,刻意声明在“外部/extern” 某个地方,有一个 foo,只能
骗过编译器,无法骗过链接器。 因为 foo 已经在源文件 .cpp 里面被声明为是它 (.cpp) 的独
宠了。(是不是有些像class 里面的 private 限制? )

而直接定义(实现)在头文件的自由函数,得加上 inline 声明:当然,到了c++时,有了成员函数Q,则直接在头文件定义(实现)的成员函数,不用加inline 声明,也默认要被编译成;"内联”函数。来归纳一下:

如果函数要被定义(实现)在头文件,那么它就得是所谓的“内联”

  • 如果是在头文件中定义的自由函数,得程序员手工加inline 修饰
  • 如果是在头文件中定义的成员函数,产就强制约定它就是“内联”的。

为什么要这样呢?

首先,先来说说这里的所谓的“内联”是什么意义

但事实上这里的“内联”得加引号了,因为它很可能不是真正意义上的内联。真正的意义上的内
联,可以理解为“内嵌”,即: 这个函数并不一定实现为函数。

  • 函数的的意义是:一份代码,多处调用。比如说,A函数有十行代码,然后有五个地方调用,并不会产生50行代码。
  • 内联的意义则是:一份代码,到处使用。比如说,A内联有十行代码,然后有五个地方调用,则至少会产生50行代码

但是,以上的解释,都是“古老”的内联规定了。现在的内联,它是不是真正的函数,C/C++程序
员已经很难去控制了。在头文件中的函数之所以被约定为必须是“内联”。只是为了做个记号,好
让编译器知道:

1.如果有可能将它实现真正内联,那就把它实现为真正内联(就是它并不是真的函数,而是一段准
备到处塞入的代码) ;
2.如果没办法将它实现为真正内联,那就得将它实现为普通函数,于是,烦请编译器你帮处理
下:第一次遇上这个函数,先偷偷生成一个源文件,然后将这段函数的全部代码,从头文件中移
到那个源文件中去,以保障这个函数确实位于某个源文件里?

这就又产生两个问题

  • 第1.为什么有个函数无法真正实现为内联?
  • 第2.干嘛(真正的) 函数一定要放在源文件里编译?

问题1比较简单: 一段代码并不能无条件到处“塞”,比如结构过于复杂或体积过大的代码有时不
好或非常不合适于到处“塞”。具体展现内容就又多了,这里不扯 (反正也不重要)。


问题2: C/C++编译时,就是一个源文件作为编译单元(最小编译单位)的:一个源文件被编译
后,会先得到中间(临时)文件(也称为 目标文件,所以有时会以obi 作扩展名):这个源文件
(及其所包含的头文件们)的全部编译结果就放在这个中间文件里,比如 acpp会编译得到 a.ob
b.cpp会编译得到 b.obi


头文件%就不同了,头文件会被多个源文件各自包含。假设 .cpp 和 b.cpp 都包含了 i.hpp,然后
i.hpp 里有个 foo函数的完整实现,那么,现在这个 foo 函数,是在 a.obiq,还是 b.obi 里呢?
答:二者都有。于是,在链接时,链接器会报错: 怎么搞的,竟然有 一模一样的 foo?


怎么决呢?其其实以C++编译器的照明程度,基本上一猜就是能猜出这人函教肯定得特殊外理
下。要么是在生成时,特意生成一个 i.cpp 来存放 foo,于是foo就会被生成在程序员所不知道的
.obi里。要么就在链接时学习后羿,干掉所有重复的,只留一个。c 编译器得和历史上的某些旧设
置兼容,所以要求程序员写个“inline”以示授权编译开射,而所以C++编译器 只要看到是在头
文件里定义的成员函数(成员函数是C++语言特有的,肯定不是C,不会有历史包袱),就知道怎
么外理了......

所以,你说的必须 inline + static% 是什么? 好歹要给个“网上说要加static”的例子代码嘛?

除了上面说的来自C的,在头文件中定义自由函数的情况,别的时候,建议都不要去写inline。要不
要inline (真实的inline) ,交给编译器我们的给的编译优化级别就好

如果是比较纯粹C++的话,源文件里使用static的用法,也可以改为使用 匿名namespace来实现,

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/626842
推荐阅读
相关标签
  

闽ICP备14008679号