網(wǎng)站首頁 編程語言 正文
一.inline的作用(內(nèi)聯(lián)函數(shù))
我們使用關鍵字inline和函數(shù)定義一起就可以創(chuàng)建一個內(nèi)聯(lián)函數(shù),它的作用就是減少函數(shù)調(diào)用的開銷,假如我們的程序中有一個函數(shù)會頻繁的被調(diào)用,這樣使程序的運行速度十分緩慢,那么我們使用內(nèi)聯(lián)函數(shù),就可以解決這種問題,提高程序的運行效率.
內(nèi)聯(lián)函數(shù)的定義:
inline void add(int a, int b){ return a+b; }
上面這個就是一個內(nèi)聯(lián)函數(shù),假如我們的程序中頻繁使用add操作時,將其聲明為內(nèi)聯(lián)函數(shù)就可以減少調(diào)用開銷提高效率.
注意:?
1.inline關鍵字是一種"用于實現(xiàn)的關鍵字",而不是"用于聲明的關鍵字", 換句話說inline只有放在函數(shù)的定義前,才有可能使該函數(shù)成為內(nèi)聯(lián)函數(shù),放在函數(shù)聲明前無效.
2.另外一點是:在c++的類中定義的成員函數(shù)默認就是內(nèi)聯(lián)函數(shù),但前提是在類中定義,因為我們正常的定義類的方式是在頭文件中聲明類的成員變量和成員函數(shù),在原文件中對類的成員函數(shù)進行定義,此時成員函數(shù)的定義發(fā)生在類外,所以自然就不再是內(nèi)聯(lián)函數(shù)了,如果還要讓其成為內(nèi)聯(lián)函數(shù),就需要我們手動添加inline.
3.至于第一點中我為什么要說可能使該函數(shù)成為內(nèi)聯(lián)函數(shù),是因為inline是一種推薦型關鍵字,他并不保證該函數(shù)一定會成為內(nèi)聯(lián)函數(shù),而是編譯器在編譯的時候獲取有inline建議的函數(shù)對其規(guī)模,內(nèi)容,方法等要素進行判斷,如果滿足編譯器要求該函數(shù)會成為內(nèi)聯(lián)函數(shù),反之不會成為內(nèi)聯(lián)函數(shù),因此成不成內(nèi)聯(lián)函數(shù)完全由編譯器說了算.
二.inline的實現(xiàn)(注意debug模式下內(nèi)聯(lián)函數(shù)不會展開)
既然內(nèi)聯(lián)函數(shù)可以減小函數(shù)的調(diào)用開銷,那么他是怎么實現(xiàn)的呢?非常簡單,我們在所有調(diào)用內(nèi)聯(lián)函數(shù)的地方將其代碼展開,這樣雖然會使代碼的的量增加,但是減少了調(diào)用的開銷,是一種典型的空間換時間的做法.
我們將編譯器調(diào)到Release模式下使用內(nèi)聯(lián)函數(shù),在匯編指令下就能看見其實現(xiàn)的方式.
源碼:
#includeusing namespace std; inline int add(int a, int b) { return 0; } int main() { int b=add(1, 2); cout << b << endl; return 0; }
(debug模式)反匯編:
在debug模式下我們可以清楚的看到,在程序運行到add函數(shù)時,進行了2和1兩個參數(shù)的壓棧,以及add函數(shù)的調(diào)用.
(Release模式)反匯編:
此時我們可以看到,像之前的那種參數(shù)壓棧,函數(shù)調(diào)用沒有了,那就是內(nèi)聯(lián)函數(shù),實現(xiàn)成功了,在這里不會再繼續(xù)調(diào)用add函數(shù)了,而是將add函數(shù)直接展開,將其代碼放在這里直接進行a+b的運算,避免函數(shù)的調(diào)用,增加其運行效率.
三.使用inline的注意事項
在上面我說到了,使用內(nèi)聯(lián)函數(shù)是一種消耗空間獲得時間的方法,因此我們得把握好其中的度,當程序的規(guī)模過大時,其代碼的運行的開銷已經(jīng)遠遠超過我們函數(shù)調(diào)用的開銷時,此時收益非常小,再使用內(nèi)聯(lián)函數(shù)就沒有必要了,并且函數(shù)內(nèi)存在遞歸或者循環(huán)時也不能使用內(nèi)聯(lián)函數(shù),編譯器也不會將其變?yōu)閮?nèi)聯(lián)函數(shù).
源碼:
#includeusing namespace std; inline int mul(int a) {//求a的階乘 if (a <= 0) { return 1; } return a * mul(a - 1); } int main() { int b=mul(10); cout << b << endl; return 0; }
(Release模式)反匯編:
此時在Release模式的反匯編指令中我們看到mul函數(shù)并沒有被展開,而是進行了函數(shù)調(diào)用,說明編譯器并沒有將其變?yōu)閮?nèi)聯(lián)函數(shù).
四.inline和預處理的區(qū)別
我們知道預處理階段會發(fā)生宏替換這一行為,宏替換也就是將代碼中用到宏的地方用宏定義的代碼或數(shù)據(jù)與宏進行替換,inline也是將函數(shù)中的代碼復制到調(diào)用內(nèi)聯(lián)函數(shù)的地方,那么他們有什么區(qū)別呢?宏替換只是單純的替換并不安全,而內(nèi)聯(lián)函數(shù)在使用的時候,編譯器會對內(nèi)聯(lián)函數(shù)調(diào)用的正確性進行判斷如果不正確則該操作就不會發(fā)生,因此其更加安全,所以在c++中所有的宏代碼,都應該使用內(nèi)聯(lián)函數(shù)進行取代.?
總結(jié)
原文鏈接:https://blog.csdn.net/weixin_49312527/article/details/123503198
相關推薦
- 2022-04-10 element input輸入框千分位無法回顯問題解決方法
- 2022-08-03 python如何實現(xiàn)排序,并標上序號_python
- 2022-01-30 tortoiseGit推送每次需要輸入密碼,解決方案
- 2022-04-27 C++的指針,引用和STL詳解_C 語言
- 2022-06-22 Android使用EventBus多次接收消息_Android
- 2023-11-12 ip link set eno2 down后centos無法聯(lián)網(wǎng);centos7.0,二次啟動后無法
- 2022-10-02 react如何獲取state的值并更新使用_React
- 2023-03-27 Android?Framework原理Binder驅(qū)動源碼解析_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支