目錄
一、引用
1.引用的概念
2.引用的特性
3.常引用
4.引用的使用場(chǎng)景
?????????做參數(shù)
?????????做返回值
5.傳值、傳引用效率比較
值和引用的作為返回值類型的性能比較
6.引用和指針的區(qū)別
?引用和指針的不同點(diǎn)
?二、內(nèi)聯(lián)函數(shù)
1.內(nèi)聯(lián)函數(shù)的概念
2.內(nèi)聯(lián)函數(shù)的特性
3.宏與內(nèi)聯(lián)函數(shù)
宏的優(yōu)缺點(diǎn)
??優(yōu)點(diǎn):
??缺點(diǎn):
在C++中代替宏的方法
前言
?????????前面我們講了C語(yǔ)言的基礎(chǔ)知識(shí),也了解了一些數(shù)據(jù)結(jié)構(gòu),并且講了有關(guān)C++的命名空間的一些知識(shí)點(diǎn)以及關(guān)于C++的缺省參數(shù)、函數(shù)重載,也相信大家都掌握的不錯(cuò),接下來(lái)博主將會(huì)帶領(lǐng)大家繼續(xù)學(xué)習(xí)有關(guān)C++的知識(shí)點(diǎn)——引用 和 內(nèi)聯(lián)函數(shù)。下面話不多說(shuō)坐穩(wěn)扶好咱們要開車了。
一、引用
1.引用的概念
????????在C++中,引用是一種用于簡(jiǎn)化變量操作的概念。通過(guò)引用,可以創(chuàng)建一個(gè)已存在變量的別名,用于在程序中對(duì)原變量進(jìn)行操作,簡(jiǎn)單來(lái)說(shuō)引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空間,它和它引用的變量共用同一塊內(nèi)存空間。引用的使用方式是在變量聲明時(shí)在其類型前加上&符號(hào),例如:
int num = 10;
int& ref = num;// 引用聲明和初始化
????????在上面的例子中,ref 是對(duì) num 的引用,它們指向同一個(gè)內(nèi)存位置。因此,對(duì) ref 的操作實(shí)際上是對(duì) num 的操作,它們完全等價(jià)。
?????????類型& 引用變量名(對(duì)象名) = 引用實(shí)體;
void TestRef()
{
int a = 10;
int& ra = a;//<====定義引用類型
printf("%p\n", &a);
printf("%p\n", &ra);
}
??????????注意:引用類型必須和引用實(shí)體是同種類型的!??!
2.引用的特性
1. 引用在定義時(shí)必須初始化
2. 一個(gè)變量可以有多個(gè)引用
3. 引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體
4.傳遞函數(shù)參數(shù):通過(guò)引用傳遞函數(shù)參數(shù),可以在函數(shù)內(nèi)部修改原始變量的值,而無(wú)需進(jìn)行拷貝。
3.常引用
void TestConstRef()
{
const int a = 10;
//int& ra = a; // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),a為常量
const int& ra = a;
// int& b = 10; // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),b為常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 該語(yǔ)句編譯時(shí)會(huì)出錯(cuò),類型不同
const int& rd = d;
}
4.引用的使用場(chǎng)景
?????????做參數(shù)
void Swap(int& left, int& right)
{
int temp = left;
left = right;
right = temp;
}
?????????做返回值
int& Count()
{
static int n = 0;
n++;
// ... 代碼塊
return n;
}
??注意:如果函數(shù)返回時(shí),出了函數(shù)作用域,如果返回對(duì)象還在(還沒(méi)還給系統(tǒng)),則可以使用引用返回,如果已經(jīng)還給系統(tǒng)了,則必須使用傳值返回。
5.傳值、傳引用效率比較
????????以值作為參數(shù)或者返回值類型,在傳參和返回期間,函數(shù)不會(huì)直接傳遞實(shí)參或者將變量本身直接返回,而是傳遞實(shí)參或者返回變量的一份臨時(shí)的拷貝,因此用值作為參數(shù)或者返回值類型,效率是非常低下的,尤其是當(dāng)參數(shù)或者返回值類型非常大時(shí),效率就更低。
#include <time.h>
struct A{ int a[10000]; };
void TestFunc1(A a){}
void TestFunc2(A& a){}
void TestRefAndValue()
{
A a;
// 以值作為函數(shù)參數(shù)
size_t begin1 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc1(a);
size_t end1 = clock();
// 以引用作為函數(shù)參數(shù)
size_t begin2 = clock();
for (size_t i = 0; i < 10000; ++i)
TestFunc2(a);
size_t end2 = clock();
// 分別計(jì)算兩個(gè)函數(shù)運(yùn)行結(jié)束后的時(shí)間
cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
值和引用的作為返回值類型的性能比較
#include <time.h>
struct A{ int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a;}
// 引用返回
A& TestFunc2(){ return a;}
void TestReturnByRefOrValue()
{
// 以值作為函數(shù)的返回值類型
size_t begin1 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc1();
size_t end1 = clock();
// 以引用作為函數(shù)的返回值類型
size_t begin2 = clock();
for (size_t i = 0; i < 100000; ++i)
TestFunc2();
size_t end2 = clock();
// 計(jì)算兩個(gè)函數(shù)運(yùn)算完成之后的時(shí)間
cout << "TestFunc1 time:" << end1 - begin1 << endl;
cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
????????通過(guò)上述代碼的比較,發(fā)現(xiàn)傳值和指針在作為傳參以及返回值類型上效率相差很大。
6.引用和指針的區(qū)別
在語(yǔ)法概念上引用就是一個(gè)別名,沒(méi)有獨(dú)立空間,和其引用實(shí)體共用同一塊空間。
int main()
{
int a = 10;
int& ra = a;
cout<<"&a = "<<&a<<endl;
cout<<"&ra = "<<&ra<<endl;
return 0;
}
??在底層實(shí)現(xiàn)上實(shí)際是有空間的,因?yàn)橐檬前凑罩羔樂(lè)绞絹?lái)實(shí)現(xiàn)的。
int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}
我們來(lái)看下引用和指針的匯編代碼對(duì)比
?引用和指針的不同點(diǎn)
??引用概念上定義一個(gè)變量的別名,指針存儲(chǔ)一個(gè)變量地址。
??引用在定義時(shí)必須初始化,指針沒(méi)有要求
??引用在初始化時(shí)引用一個(gè)實(shí)體后,就不能再引用其他實(shí)體,而指針可以在任何時(shí)候指向任何一個(gè)同類型實(shí)體
??沒(méi)有NULL引用,但有NULL指針
??在sizeof中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32位平臺(tái)下占4個(gè)字節(jié))
??引用自加即引用的實(shí)體增加1,指針自加即指針向后偏移一個(gè)類型的大小??有多級(jí)指針,但是沒(méi)有多級(jí)引用
??訪問(wèn)實(shí)體方式不同,指針需要顯式解引用,引用編譯器自己處理
??引用比指針使用起來(lái)相對(duì)更安全
?二、內(nèi)聯(lián)函數(shù)
1.內(nèi)聯(lián)函數(shù)的概念
????????以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開,沒(méi)有函數(shù)調(diào)用建立棧幀的開銷,內(nèi)聯(lián)函數(shù)提升程序運(yùn)行的效率。
?如果在上述函數(shù)前增加inline關(guān)鍵字將其改成內(nèi)聯(lián)函數(shù),在編譯期間編譯器會(huì)用函數(shù)體替換函數(shù)的
調(diào)用。
2.內(nèi)聯(lián)函數(shù)的特性
?inline是一種以空間換時(shí)間的做法,如果編譯器將函數(shù)當(dāng)成內(nèi)聯(lián)函數(shù)處理,在編譯階段,會(huì)
用函數(shù)體替換函數(shù)調(diào)用。
缺陷:可能會(huì)使目標(biāo)文件變大
優(yōu)勢(shì):少了調(diào)用開銷,提高程序運(yùn)行效率。
?inline對(duì)于編譯器而言只是一個(gè)建議,不同編譯器關(guān)于inline實(shí)現(xiàn)機(jī)制可能不同,一般建議:將函數(shù)規(guī)模較小(即函數(shù)不是很長(zhǎng),具體沒(méi)有準(zhǔn)確的說(shuō)法,取決于編譯器內(nèi)部實(shí)現(xiàn))、不是遞歸、且頻繁調(diào)用的函數(shù)采用inline修飾,否則編譯器會(huì)忽略inline特性。
?inline不建議聲明和定義分離,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開,就沒(méi)有函數(shù)地址了,鏈接就會(huì)找不到。
3.宏與內(nèi)聯(lián)函數(shù)
宏的優(yōu)缺點(diǎn)
??優(yōu)點(diǎn):
????????1.增強(qiáng)代碼的復(fù)用性。?
????????2.提高性能。
??缺點(diǎn):
????????1.不方便調(diào)試宏。(因?yàn)轭A(yù)編譯階段進(jìn)行了替換)
????????2.導(dǎo)致代碼可讀性差,可維護(hù)性差,容易誤用。
????????3.沒(méi)有類型安全的檢查 。
在C++中代替宏的方法
1. 常量定義換用const enum文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-602782.html
2. 短小函數(shù)定義換用內(nèi)聯(lián)函數(shù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-602782.html
到了這里,關(guān)于【C++入門到精通】C++入門 —— 引用、內(nèi)聯(lián)函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!