網站首頁 編程語言 正文
inline 是什么?
inline是C++ 11引入的關鍵字,在函數聲明or定義時,返回類型前加上關鍵字inline,即可以把函數指定為內聯函數。
引入inline的目的是什么?
目的是解決一些頻繁調用的函數大量消耗棧空間(棧內存)的問題。另一方面用于替換C語言的宏(相比較宏是無法在進行類型檢查)
內聯函數的特點
- 內聯函數的函數內容本質上是寫在調用內聯函數的地方;
- 內聯函數本質上沒有入棧出棧的開銷;
- 和宏定義相比,內聯函數更加安全,編譯器會根據函數的要求進行嚴格的類型和作用域檢查,保證調用無誤;
- 內聯函數一般上不包含循環、遞歸、switch或較長的代碼 等復雜操作;
- 類聲明中定義的函數,除虛函數外的其他函數都會自動隱式地當成內聯函數;
內聯函數的寫法
這里的一個關鍵點,inline必須與函數定義放在一起才能使函數成為內聯函數,僅將inline放在函數聲明前面不起任何作用。
inline是一種“用于實現”的關鍵字,不是一種“用于聲明”的關鍵字。
//在頭文件中可以進行顯示聲明
//方式1 加 inline(建議使用)
inline int TestFunc(int a, int b);
//方式2 原始常見聲明方式
int TestFunc(int a, int b);
//在源文件中定義
//正確
inline int TestFunc(int a, int b){
//do something
return 0;
}
//錯誤
int TestFunc(int a, int b){
//do something
return 0;
}
隱式內聯和顯式內聯
隱式內聯的寫法
class CppObj {
int TestFuncA() { return 0; } //隱式內聯
vitrual int TestFuncB() { return 0; } //虛函數不會進行隱式內聯
}
顯式內聯的寫法
class CppObj {
int TestFuncA();
inline int TestFuncB();
vitrual int TestFuncC();
}
inline int CppObj::TestFuncA() { //顯式內聯
return 0;
}
inline int CppObj::TestFuncB() { //顯式內聯
return 0;
}
inline 函數的編譯器處理
inline函數僅僅是一個開發者對編譯器的建議,至于最后能否真正內聯,需要看編譯器的意思。如果編譯器判定函數不復雜,能在調用點展開,就會真正內聯。
內聯函數優缺點
- 優點
- 內聯函數相比宏函數來說,在代碼調用時會做安全檢查和類型轉換(同普通函數),而宏定義則不會;
- 宏定義不可以在運行時可調試,但內聯函數可以;
- 內聯函數同宏函數一樣會在被調用處進行展開,無需參數壓棧、棧幀開辟與回收,結果返回等,從而能提高代碼的運行速度。
- 缺點
- 代碼膨脹。內聯是以代碼膨脹(復制)為代價,是典型的以空間換時間的做法。
- 內聯函數不可控。內聯函數只是編碼者對編譯器的建議,是否對函數內聯,最終決定權在于編譯器。
- inline 函數無法隨著函數庫升級而升級。inline函數的改變需要重新編譯,不像 non-inline 可以直接鏈接。
虛函數可以是內聯函數嗎?
- 虛函數可以是內聯函數;
- inline是可以修飾虛函數;
虛函數內聯條件?
可以內聯的條件,編譯器具有實際對象而不是對象的指針或引用時才會,所以當虛函數表現多態性的時候不能內聯。
虛函數表現多態性的時候不能內聯
內聯是在編譯期進行的,但虛函數的多態性在運行期,所以編譯器無法知曉運行期具體調用哪個代碼
代碼釋義
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
inline virtual void FuncName() { cout << "this is Base " << endl; }
};
class Derived : public Base {
public:
inline virtual void FuncName() { cout << "this is Derived" << endl; }
};
int main()
{
// 編譯器具有實際對象,所以它可以是內聯的.
Base b;
b.FuncName();
// 編譯器具有對象的指針,呈現多態性,運行時期才能確定,所以不能內聯。
Base* p = new Derived();
p->FuncName();
delete p;
p = nullptr;
system("pause");
return 0;
}
參考連接:
Are “inline virtual” member functions ever actually “inlined”?
總結?
原文鏈接:https://blog.csdn.net/u013052326/article/details/127605937
相關推薦
- 2022-06-06 基于VSTS的Xamarin.Android持續集成步驟詳解_Android
- 2023-01-20 Python輸入圓半徑,計算圓周長和面積的實現方式_python
- 2022-09-10 Python并發編程多進程,多線程及GIL全局解釋器鎖_python
- 2022-06-13 ASP.NET?Core中使用多環境_實用技巧
- 2022-02-23 圖片返回base64數據渲染為圖片的處理
- 2022-06-24 使用python?matplotlib畫折線圖實例代碼_python
- 2022-07-06 Python3?DataFrame缺失值的處理方法_python
- 2022-05-08 繼docker之后podman容器技術崛起_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支