c++ 内联函数

使用关键字inline来定义,把函数调用处直接进行代码替换。
实际上是否进行代码替换由编译器进行最终决定。此外内联函数被本身所在cpp文件中调用时,才会有如同普通函数一样的地址,具体影响看下面例子。


内联函数的定义问题

1.编译器编译时以cpp为一个编译单元,别的cpp编译完就彻底过去了,对当前编译cpp不造成影响。所以,只有内联函数的定义对编译器编译可见时,才能以代码替换形式实现真正的内联函数。

2.仅在A.cpp定义内联函数,B.cpp声明了该函数,但在B中仍然是不可用,出错的。
在A.cpp和B.cpp中定义一样的内联函数,不会造成重定义。

3.奇异效果:
为减少烦躁心理,以下示例cpp代码中略去#include "stdafx.h"、#include <iostream>、using namespace std;

A.cpp:
inline void m()
{
    cout << "A";
}
Main.cpp:
extern void m();
int main()
{
    m();
    return 0;
}

这样将会报错无法解析的外部符号。
但是,把A.cpp添加修改如下

A.cpp:
inline void m()
{
    cout << "A";
}
void ma()
{
    m();
}

这样又是可以通过编译的,能正确输出。
前者是编译完后,内联函数没有函数地址,链接时自然找不到。后者新增ma()中调用了m(),使得编译A.cpp时让m有了函数地址(这时编辑器特意拿个特殊小本子记住:这个m()对应这个函数入口地址。不同编译器可能处理不同),连接时m()便是对各cpp可见了。

4.奇异效果x2:
类似A.cpp,写多两个:B.cpp、C.cpp

B.cpp:
inline void m()
{
    cout << "B";
}
void mb()
{
    m();
}
C.cpp:你懂的。。。

这样仍然能通过编译,编译全部cpp后,函数m()也就有3个函数地址,最后由编译器自行决定留哪一个,丢弃另外两个地址。所以,最后Main.cpp的调用输出可能是"A"、"B"、"C"中的任意一个,ma()、mb()、mc()的结果也是同理。

5.类也是一样的情况
头文件中写类,弄两个cpp分别用inline定义成员函数,然后分别写个函数调用成员函数使得成员函数有入口地址,最后在main函数中调用该成员函数时,最终结果也是编译器自主决定是哪个入口地址的。

6.总结
对于同名函数定义在不同cpp内的情况:
只用inline没有内部调用,其他cpp会外部符号无法解析(找不到定义)。错误!
只用inline且被内部调用,编译器只保留1个函数地址,结果不定但不会重定义。可以!
inline被内部调用后如同普通函数,会与不使用inline定义的普通函数产生重定义冲突。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. 引入inline关键字的原因 在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特...
    一川烟草i蓑衣阅读 431评论 0 1
  • 1、常量与宏 C++中的const常量可以替代宏常数定义: 我们还可以利用宏来定义宏代码片段: 但是宏代码块不是函...
    _Ke_阅读 664评论 0 0
  • C++ 类 & 对象 C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代...
    资深小夏阅读 183评论 0 0
  • darklovy阅读 162评论 0 0
  • 每个早晨醒来 都希望能够把自己打扮的美美的 每天给人一种特别的感觉 但是对于一柜子的衣服又不知道如何下手 哥弟为您...
    高晓涵阅读 213评论 0 0

友情链接更多精彩内容