C++示例分析內(nèi)聯(lián)函數(shù)與引用變量及函數(shù)重載的使用
1.內(nèi)聯(lián)函數(shù)
1.1為什么使用內(nèi)聯(lián)函數(shù)
- 減少上下文切換,加快程序運(yùn)行速度。
- 是對(duì)C語(yǔ)言中的宏函數(shù)的改進(jìn)。
1.2語(yǔ)法
#include<iostream> using namespace std; inline double square(double x){ return x*x; } int main(){ cout<<square(2.2)<<endl; }
其實(shí)就是在函數(shù)聲明或者定義前加上關(guān)鍵字inline
。
2.引用變量
2.1為什么要使用引用變量
- 主要用途是用作函數(shù)的形參。通過(guò)引用變量做參數(shù),函數(shù)將使用原始數(shù)據(jù),而不是其副本。
- 高效。
2.2語(yǔ)法
引用實(shí)際上就是定義一個(gè)別名。看看下面代碼:
#include<iostream> using namespace std; int main(){ int a=50; int &b=a;//定義并初始化,這里b是a的引用。 cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; cout<<"address of a:"<<&a<<endl; cout<<"address of b:"<<&b<<endl; b=100; cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; int c=200; b=c;//試圖將b作為c的引用。行不通。 cout<<"a:"<<a<<endl; cout<<"b:"<<b<<endl; cout<<"c:"<<c<<endl; cout<<"address of a:"<<&a<<endl; cout<<"address of b:"<<&b<<endl; cout<<"address of c:"<<&c<<endl; }
a:50
b:50
address of a:0x61fe14
address of b:0x61fe14
a:100
b:100
a:200
b:200
c:200
address of a:0x61fe14
address of b:0x61fe14
address of c:0x61fe10
a和b的數(shù)據(jù)地址是一樣的,這說(shuō)明b相當(dāng)于a的別名,我們改變b的值,也會(huì)改變a的值,而且后面我們?cè)噲D將b轉(zhuǎn)變?yōu)閏的引用,但是行不通,b=c這個(gè)代碼做的是賦值語(yǔ)句,相當(dāng)于a=c.
引用和指針的區(qū)別
引用在聲明的時(shí)候必須初始化
int &b;
這句話是不允許的。
引用的本質(zhì)就是指針常量。因?yàn)橐米兞恳坏┏跏蓟筒荒芨摹?/p>
int &b=a
和int* const p=&a
這兩句中b
和*p
是一模一樣的。
引用作為函數(shù)參數(shù)
#include<iostream> using namespace std; void swap(int &a,int &b){ int c; c=a; a=b; b=c; } int main(){ int a=2; int b=3; swap(a,b); cout<<a<<b<<endl; }
可以看出把引用作為參數(shù)的函數(shù),只需在聲明時(shí),把參數(shù)設(shè)置成引用即可。
臨時(shí)變量
試想一下,在參數(shù)傳遞過(guò)程中,我們把常數(shù)或者錯(cuò)誤類型的實(shí)參,傳給引用參數(shù),會(huì)發(fā)生什么?這個(gè)引用參數(shù)會(huì)變成這個(gè)實(shí)參的引用嗎?顯然不會(huì),因?yàn)槌?shù)不能修改,引用是錯(cuò)誤的,正如int &a=2;
會(huì)報(bào)錯(cuò)一樣;錯(cuò)誤類型的實(shí)參,也不能直接引用。
為了解決這個(gè)事,c++允許臨時(shí)變量的產(chǎn)生。但是只有const引用才會(huì)產(chǎn)生臨時(shí)變量,const引用不允許變量發(fā)生賦值。
總結(jié)來(lái)說(shuō),臨時(shí)變量的產(chǎn)生條件是,在傳參給const引用參數(shù)時(shí):
實(shí)參不是左值.(左值指的是const變量 和 常規(guī)變量。)
實(shí)參類型不正確且可類型轉(zhuǎn)換。
所以說(shuō),為了使得引用參數(shù)傳遞的兼容性和安全性,請(qǐng)多使用const。
#include<iostream> using namespace std; double square(const double &a){ return a*a*a; } int main(){ int a=3; cout<<square(3+a)<<endl; }
可以看出來(lái)這里square函數(shù)可以接受非左值,類型錯(cuò)誤的實(shí)參。
你可能覺(jué)得這樣做很復(fù)雜,直接使用按值傳參就行了。double square(double a)
和double square(const double &a)
,從效果來(lái)說(shuō),這兩一樣,但是我們使用第二種傳參的好處是高效,試想一下我們同時(shí)傳一個(gè)double類型的變量,const引用傳參不需要數(shù)據(jù)的拷貝,更快。
右值引用
采用 && 來(lái)對(duì)右值做引用,這么做的目的是用來(lái)實(shí)現(xiàn)移動(dòng)語(yǔ)義。
#include<iostream> using namespace std; int main(){ double a=3.1; double && b=a*1.2+2.3; cout<<b<<endl; b=3; cout<<a<<endl; cout<<b<<endl; }
6.02
3.1
3
結(jié)構(gòu)引用
引用非常適合于結(jié)構(gòu)和類
#include<iostream> using namespace std; struct apple { string name; double weight; }; apple & swap(apple &a, apple &b){ apple temp; temp=a; a=b; b=temp; return a; } int main(){ apple a={"Bob",230}; apple b={"Alice",190}; swap(a,b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; swap(swap(a,b),b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; swap(swap(swap(a,b),b),b); swap(swap(a,b),b); cout<<"a:"<<endl<<"name:"<<a.name<<endl<<"weight:"<<a.weight<<endl<<endl; cout<<"b:"<<endl<<"name:"<<b.name<<endl<<"weight:"<<b.weight<<endl<<endl; }
a:
name:Alice
weight:190b:
name:Bob
weight:230a:
name:Alice
weight:190b:
name:Bob
weight:230a:
name:Bob
weight:230b:
name:Alice
weight:190
swap()函數(shù)的返回值是一個(gè)引用變量,所以swap(swap(swap(a,b),b),b)
是合法的,且它等價(jià)于swap(a,b)
。
為何要返回引用?高效。 因?yàn)閭鹘y(tǒng)返回機(jī)制,會(huì)把返回結(jié)果復(fù)制到一個(gè)臨時(shí)位置。 但是應(yīng)該避免返回 函數(shù)終止時(shí)不再存在的內(nèi)存單元引用。例如避免返回臨時(shí)變量的引用。
2.3對(duì)于C語(yǔ)言的改進(jìn)
- 用const引用傳參傳遞 代替 按值傳遞。
- 對(duì)于要修改原始數(shù)據(jù)的函數(shù),采用引用傳參方式。
3. 函數(shù)重載
3.1默認(rèn)參數(shù)
默認(rèn)參數(shù)指的是函數(shù)調(diào)用中省略了實(shí)參時(shí)自動(dòng)使用的一個(gè)值。
如何設(shè)置默認(rèn)值?必須通過(guò)函數(shù)原型。 例如這里的void display(int a,int n=999);
這里n=999 就是默認(rèn)參數(shù) 默認(rèn)參數(shù)的作用是,不給這個(gè)參數(shù)傳參時(shí),他會(huì)采用默認(rèn)值。
#include<iostream> using namespace std; void display(int a,int n=999); int main(){ display(1); display(3,31); } void display(int a,int n){ cout<<a<<endl; cout<<n<<endl; }
1
999
3
31
3.2函數(shù)重載
默認(rèn)參數(shù)能讓我們使用不同數(shù)目的參數(shù)調(diào)用同一個(gè)函數(shù),而函數(shù)重載能讓我們使用多個(gè)同名的函數(shù)。
函數(shù)重載的關(guān)鍵是函數(shù)的參數(shù)列表–也稱函數(shù)特征標(biāo)。如果兩個(gè)函數(shù)的名字和特征標(biāo)相同,那么這兩個(gè)函數(shù)就完全相同。C++允許定義名稱相同,函數(shù)特征標(biāo)不同的函數(shù),這就是所謂的函數(shù)重載。
#include<iostream> using namespace std; struct apple{ string name; double weight; }; void print(int); void print(double); void print(char *); void print(apple &a,string str="apple",double w=100); int main(){ int a=2; double b=3.14; char c[10]="hello!"; apple d; print(a); print(b); print(c); print(d); print(d,"Alice",250); } void print(int a){ cout<<"int ="<<a<<endl; } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; } void print(apple &a,string str,double b){ a.name=str; a.weight=b; cout<<"the name:"<<a.name<<endl; cout<<"the weight:"<<a.weight<<endl; }
int =2
double =3.14
char* =hello!
the name:apple
the weight:100
the name:Alice
the weight:250
可以看出來(lái)print
函數(shù)有多個(gè)重載,現(xiàn)代編譯器會(huì)根據(jù)你傳遞的參數(shù)類型,而選擇最匹配的函數(shù)。
關(guān)于函數(shù)重載的一些細(xì)節(jié)
- 類型引用和類型本身視為同一個(gè)特征標(biāo),例如
double cube(double x);
和double cube(double &x);
是不能共存的。 - 匹配函數(shù)時(shí),會(huì)區(qū)分const和非const變量,例如
void display(char* a);
和void display(const char* a);
是函數(shù)重載。 - 請(qǐng)記住是特征標(biāo),而不是函數(shù)類型使得可以對(duì)函數(shù)進(jìn)行重載。例如
long gronk(int,float);
和double gronk(int,float);
是不能共存的。
函數(shù)重載的shortcoming
函數(shù)重載在實(shí)現(xiàn)同函數(shù)名多種功能的同時(shí),也應(yīng)當(dāng)付出代價(jià)。
標(biāo)準(zhǔn)類型轉(zhuǎn)化、強(qiáng)制匹配能力下降。
#include<iostream> using namespace std; void print(double); void print(char *); int main(){ int a=2; double b=3.14; char c[10]="hello!"; print(a); print(b); print(c); } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; }
double =2
double =3.14
char* =hello!
可以看出來(lái)這里print(a)
這里a是int類型,編譯器會(huì)將其類型轉(zhuǎn)化成double,然后調(diào)用對(duì)應(yīng)函數(shù)。
但是,我們稍微改動(dòng)一下代碼
#include<iostream> using namespace std; void print(int); void print(double); void print(char *); int main(){ int a=2; double b=3.14; char c[10]="hello!"; print(a); print(b); print(c); print(12L); } void print(int a){ cout<<"int ="<<a<<endl; } void print(double a){ cout<<"double ="<<a<<endl; } void print(char * a){ cout<<"char* ="<<a<<endl; }
這段代碼中print(12L);
會(huì)報(bào)錯(cuò),因?yàn)?code>12L是long類型的常量,如果我們?cè)囍鴱?qiáng)制匹配會(huì)發(fā)現(xiàn),12L
既可以轉(zhuǎn)化成int類型,也可以轉(zhuǎn)化成double類型,從而編譯器不知道到底調(diào)用哪個(gè)函數(shù)。
不要濫用函數(shù)重載
僅當(dāng)函數(shù)基本執(zhí)行相同的任務(wù),但使用不同類型的數(shù)據(jù)時(shí),才應(yīng)當(dāng)使用函數(shù)重載。
到此這篇關(guān)于C++示例分析內(nèi)聯(lián)函數(shù)與引用變量及函數(shù)重載的使用的文章就介紹到這了,更多相關(guān)C++內(nèi)聯(lián)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)求n階勒讓德多項(xiàng)式的方法
這篇文章主要介紹了C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)求n階勒讓德多項(xiàng)式的方法,涉及C語(yǔ)言復(fù)雜浮點(diǎn)數(shù)運(yùn)算的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-05-05C++實(shí)現(xiàn)簡(jiǎn)單版圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單版圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06c語(yǔ)言實(shí)現(xiàn)兩個(gè)值互相交換的函數(shù)
本文通過(guò)代碼給大家介紹c語(yǔ)言實(shí)現(xiàn)兩個(gè)值互相交換的函數(shù),通過(guò)實(shí)例代碼給大家講解的很詳細(xì),具有一定的參考借鑒價(jià)值,對(duì)c語(yǔ)言兩個(gè)值互換函數(shù)相關(guān)知識(shí)感興趣的朋友一起看看吧2021-05-05你真的理解C語(yǔ)言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù)
這篇文章主要介紹了你真的理解C語(yǔ)言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù),本篇將引入一個(gè)庫(kù)函數(shù)來(lái)實(shí)現(xiàn)我們希望的順序,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問(wèn)題探究
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)中約瑟夫環(huán)問(wèn)題,總的來(lái)說(shuō)這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過(guò)程。希望通過(guò)這道題能給你帶來(lái)一種解題優(yōu)化的思路2023-01-01Linux C/C++實(shí)現(xiàn)DNS客戶端請(qǐng)求域名IP的示例代碼
DNS全稱:Domain Name System,域名解析系統(tǒng),是互聯(lián)網(wǎng)的一項(xiàng)服務(wù),本文主要介紹了C/C++如何實(shí)現(xiàn)DNS客戶端請(qǐng)求域名IP,感興趣的可以了解下2024-03-03C++ Boost Fusion創(chuàng)建異構(gòu)容器詳解
Boost.Fusion 使創(chuàng)建異構(gòu)容器成為可能。例如,您可以創(chuàng)建一個(gè)向量,其第一個(gè)元素是 int,第二個(gè)元素是字符串。此外,Boost.Fusion 提供了處理異構(gòu)容器的算法。您可以將 Boost.Fusion 視為異構(gòu)容器的標(biāo)準(zhǔn)庫(kù)2022-11-11C++實(shí)現(xiàn)讀取特定路徑下文件夾及文件名的方法
這篇文章主要介紹了C++實(shí)現(xiàn)讀取特定路徑下文件夾及文件名的方法,需要的朋友可以參考下2014-07-07C語(yǔ)言實(shí)現(xiàn)“幸運(yùn)數(shù)”的實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)“幸運(yùn)數(shù)”的實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07