C++內聯函數(inline function)

c++從c中繼承的一個重要特征就是效率。假如c++的效率明顯低于c的效率,那么就會有很大的一批程序員不去使用c++了。

c中我們經常把一些短并且執行頻繁的計算寫成宏,而不是函數,這樣做的理由是為了執行效率,宏可以避免函數調用的開銷,這些都由預處理來完成。

但是在c++出現之后,使用預處理宏會出現兩個問題:

1.第一個在c中也會出現,宏看起來像一個函數調用,但是會有隱藏一些難以發現的錯誤。

2.第二個問題是c++特有的,預處理器不允許訪問類的成員,也就是說預處理器宏不能用作類類的成員函數。

?

為了保持預處理宏的效率又增加安全性,而且還能像一般成員函數那樣可以在類里訪問自如,c++引入了內聯函數(inline function).

?內聯函數為了繼承宏函數的效率,沒有函數調用時開銷,然后又可以像普通函數那樣,可以進行參數,返回值類型的安全檢查,又可以作為成員函數。

?

預處理宏的缺陷

預處理器宏存在問題的關鍵是我們可能認為預處理器的行為和編譯器的行為是一樣的。當然也是由于宏函數調用和函數調用在外表看起來是一樣的,因為也容易被混淆。但是其中也會有一些微妙的問題出現:

問題一:

#define ADD(x,y) x+y
inline int Add(int x,int y){return x + y;
}
void test(){int ret1 = ADD(10, 20) * 10; //希望的結果是300int ret2 = Add(10, 20) * 10; //希望結果也是300cout << "ret1:" << ret1 << endl; //210cout << "ret2:" << ret2 << endl; //300
}

問題二:

#define COMPARE(x,y) ((x) < (y) ? (x) : (y))
int Compare(int x,int y){return x < y ? x : y;
}
void test02(){int a = 1;int b = 3;//cout << "COMPARE(++a, b):" << COMPARE(++a, b) << endl; // 3cout << "Compare(int x,int y):" << Compare(++a, b) << endl; //2
}

問題三:

預定義宏函數沒有作用域概念,無法作為一個類的成員函數,也就是說預定義宏沒有辦法表示類的范圍。

?

內聯函數基本概念

c++中,預定義宏的概念是用內聯函數來實現的,而內聯函數本身也是一個真正的函數。內聯函數具有普通函數的所有行為。唯一不同之處在于內聯函數會在適當的地方像預定義宏一樣展開,所以不需要函數調用的開銷。因此應該不使用宏,使用內聯函數

n?在普通函數(非成員函數)函數前面加上inline關鍵字使之成為內聯函數。但是必須注意必須函數體和聲明結合在一起,否則編譯器將它作為普通函數來對待。

inline?void?func(int?a);

以上寫法沒有任何效果,僅僅是聲明函數,應該如下方式來做:

inline?int?func(int?a){return?++;}

注意: 編譯器將會檢查函數參數列表使用是否正確,并返回值(進行必要的轉換)。這些事預處理器無法完成的。

內聯函數的確占用空間,但是內聯函數相對于普通函數的優勢只是省去了函數調用時候的壓棧,跳轉,返回的開銷。我們可以理解為內聯函數是以空間換時間

?

類內部的內聯函數

為了定義內聯函數,通常必須在函數定義前面放一個inline關鍵字。但是在類內部定義內聯函數時并不是必須的。任何在類內部定義的函數自動成為內聯函數。

class Person{
public:Person(){ cout << "構造函數!" << endl; }void PrintPerson(){ cout << "輸出Person!" << endl; }
}

?

構造函數Person,成員函數PrintPerson在類的內部定義,自動成為內聯函數。

?

內聯函數和編譯器

內聯函數并不是何時何地都有效,為了理解內聯函數何時有效,應該要知道編譯器碰到內聯函數會怎么處理?

對于任何類型的函數,編譯器會將函數類型(包括函數名字,參數類型,返回值類型)放入到符號表中。同樣,當編譯器看到內聯函數,并且對內聯函數體進行分析沒有發現錯誤時,也會將內聯函數放入符號表。

當調用一個內聯函數的時候,編譯器首先確保傳入參數類型是正確匹配的,或者如果類型不正完全匹配,但是可以將其轉換為正確類型,并且返回值在目標表達式里匹配正確類型,或者可以轉換為目標類型,內聯函數就會直接替換函數調用,這就消除了函數調用的開銷。假如內聯函數是成員函數,對象this指針也會被放入合適位置。

類型檢查和類型轉換、包括在合適位置放入對象this指針這些都是預處理器不能完成的。

?

但是c++內聯編譯會有一些限制,以下情況編譯器可能考慮不會將函數進行內聯編譯:

ü?不能存在任何形式的循環語句

ü?不能存在過多的條件判斷語句

ü?函數體不能過于龐大

ü?不能對函數進行取址操作

?

內聯僅僅只是給編譯器一個建議,編譯器不一定會接受這種建議,如果你沒有將函數聲明為內聯函數,那么編譯器也可能將此函數做內聯編譯。一個好的編譯器將會內聯小的、簡單的函數。

轉載于:https://www.cnblogs.com/mmc9527/p/10429683.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/278273.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/278273.shtml
英文地址,請注明出處:http://en.pswp.cn/news/278273.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GreenPlum數據庫故障恢復測試

本文介紹gpdb的master故障及恢復測試以及segment故障恢復測試。 環境介紹&#xff1a;Gpdb版本&#xff1a;5.5.0 二進制版本操作系統版本&#xff1a; centos linux 7.0Master segment: 192.168.1.225/24 hostname: mfsmasterStadnby segemnt: 192.168.1.227/24 hostname: ser…

書評:Just the Computer Essentials(Vista)

Normally we try and focus on articles about how to customize your computer, but today we’ll take a break from that and do a book review. This is something I’ve not done before, so any suggestions or questions will be welcomed in the comments. 通常&#x…

RxSwift筆記七其他操作符

簡介 git地址: https://github.com/ReactiveX/RxSwift參考資料:http://t.swift.gg/d/2-rxswiftReactiveX是通過可觀察的流實現異步編程的一種API&#xff0c;它結合了觀察者模式、迭代器模式和函數式編程的精華&#xff0c;RxSwift 是 ReactiveX 編程思想的一種實現。 復制代碼…

python學習

為了學會能學&#xff0c;不負時間&#xff0c;為了那簡練的美&#xff01; 為了一片新天地。 /t 對齊 python : # 99乘法表i 0while i < 9 : i 1 j 0 while j < i : j 1 print(j ,* , i,"" , i*j , end\t) #空格不能對齊 制表符…

hey 安裝_如何在助理揚聲器上調整“ Hey Google”的靈敏度

hey 安裝Vantage_DS/ShutterstockVantage_DS / ShutterstockThe Google Assistant is a useful tool that allows you to control your smart home, check the weather, and more. Unfortunately, the Assistant might not hear you in a noisy environment or it might activa…

EXCEL如何進行多條件的數據查找返回

在使用EXCEL時經常會碰到一個表里的同一款產品每天的銷量都不一樣&#xff0c;然后我們需要查導出每一款產品每天的銷量&#xff0c;即一對多條件查找。這個教復雜&#xff0c;我們要用到好幾個函數的綜合&#xff0c;下面小編來教你吧。 工具/原料 EXCEL軟件&#xff08;本文使…

如何將Google幻燈片轉換為PowerPoint

If someone sent you a presentation on Google Slides, but you’d rather work on it in Microsoft PowerPoint, you can easily convert it to a .pptx file in just a few simple steps. Here’s how it’s done. 如果有人在Google幻燈片上向您發送了演示文稿&#xff0c;但…

Linux 常用命令:文本查看篇

前言 Linux常用命令中&#xff0c;除了cat還有很多其他用于文本查看的命令。本文將簡單介紹一下這些文本查看的命令。 全文本顯示--cat cat可能是常用的一個文本查看命令了&#xff0c;使用方法也很簡單&#xff1a; cat file #全文本顯示在終端cat -n file #顯示全文本&#…

XP調整禁用頁面文件

NOTE: You shouldn’t disable your page file unless you really really know what you are doing. 注意&#xff1a;除非您真的很清楚自己在做什么&#xff0c;否則不應該禁用頁面文件。 If your computer has 1 GB of RAM or more, disabling the page file can speed up XP…

復制數據庫

1.首先手動創建新的數據庫 CREATE DATABASE new-DB DEFAULT CHARACTER SET utf8mb4; 2.使用mysqldump命令。結果&#xff0c;會連同數據一起復制過去。 mysqldump old-DB -u root -pXX --add-drop-table | mysql new-DB -u root -pXX轉載于:https://www.cnblogs.com/clcliangc…

labelme2coco問題:TypeError: Object of type 'int64' is not JSON serializable

最近在做MaskRCNN 在自己的數據&#xff08;labelme&#xff09;轉為COCOjson格式遇到問題&#xff1a;TypeError: Object of type int64 is not JSON serializable 原因是numpy的數據類型不能被json兼容 最簡單的做法是自己寫一個序列類 class MyEncoder(json.JSONEncoder):de…

如何在Windows 10的命令提示符中更改目錄

One of the first things you’ll need to learn as you become more familiar with Command Prompt on Windows 10 is how to change directories in the operating system’s file system. There are a few ways you can do this, so we’ll walk you through them. 隨著您對…

jQuery 購物車

html代碼 <!--shoppingCar start--> <table id"TB"> <tr> <td colspan"7" class"title"> <div class"img_box"> <div class"logo_box"> <img src"img/jd…

MySQL優化總結

2019獨角獸企業重金招聘Python工程師標準>>> 從這幾天看MySQL性能優化來看&#xff0c;基本的思路就是分分分&#xff0e;&#xff0e;&#xff0e; 1&#xff0c;分讀&#xff0c;用緩存來分攤讀表的壓力; 2&#xff0c;讀寫分離&#xff0c;主從分離&#xff0c;寫…

瘋狂java講義

封裝&#xff1a; 封裝&#xff1a;將對象狀態信息隱藏在對象內部&#xff0c;不允許外部程序直接訪問對象內部信息&#xff0c;而是用類所提供的方法訪問和操作。訪問控制符&#xff1a;private&#xff08;當前類訪問權&#xff09; ,protected&#xff08;子類訪問&#xff…

將背景色添加到Word 2007文檔中

Instead of using the standard white background with Word documents, here is how to add some background color to spice up your documents. 代替在Word文檔中使用標準的白色背景&#xff0c;這是如何添加一些背景顏色來為文檔增添色彩。 Open your word document and ch…

jquery實現增刪改(偽)-老男孩作業day13

使用jquery進行&#xff0c;文件的編寫&#xff0c;實現自增id,刪除&#xff0c;添加&#xff0c;編輯模式。 jquery放在本地&#xff0c;src"jquery_js.js" 可以改成其他&#xff0c;或者在線的路徑 readme<!DOCTYPE html> <html lang"en"> &…

uoj#119. 【UR #8】決戰圓錐曲線(線段樹+復雜度分析)

題解 傳送門 題解 然而要我來說我感覺只是個爆搜啊…… //minamoto #include<bits/stdc.h> #define R register #define ll long long #define ls (p<<1) #define rs (p<<1|1) #define fp(i,a,b) for(R int ia,Ib1;i<I;i) #define fd(i,a,b) for(R int ia…

如何在Raspberry Pi上設置兩因素身份驗證

Kiklas/ShutterstockKiklas /快門The Raspberry Pi is everywhere now, which is why it’s caught the eye of threat actors and cybercriminals. We’ll show you how to secure your Pi with two-factor authentication. Raspberry Pi現在無處不在&#xff0c;這就是為什么…

Laravel Passport里的授權類型介紹

本文來自pilishen.com----原文鏈接; 歡迎來和pilishen一起學習php&Laravel&#xff1b;學習群&#xff1a;109256050OAuth2是一個安全框架&#xff0c;控制著程序受保護部分的準入&#xff0c;主要是控制不同的客戶端如何來調取API&#xff0c;保證它們在請求相應資源的時候…