北京網(wǎng)站建設新聞國產長尾關鍵詞拘挖掘
目錄
1. 引用
1.1 引用特性
1.2 常引用
1.2.1 權限放大
?1.2.2 權限縮小
1.3 使用場景
1.3.1 傳參?
1.3.2 做返回值
?1.4 傳值和傳引用的效率比較
?1.5 引用和指針的區(qū)別
2. 內聯(lián)函數(shù)
?2.1 inline
?2.2 特性
1. 引用
? ? ? ? 在C++中,引入了一個新的概念引用,與傳統(tǒng)的定義變量不同,傳統(tǒng)的定義變量是新開一份空間來存儲數(shù)據(jù),而引用則是給一個已經(jīng)存在的空間起一個別名,它和引用的變量共用同一份空間。
1.1 引用特性
- 引用必須在定義的時候初始化
- 一個變量可以有多個引用
- 引用一旦引用一個實體就不能在引用其他實體
int a = 0;int& b = a;int& c = a;cout << a << ' ' << b << ' ' << c << endl;cout << &a << ' ' << &b << ' ' << &c << endl;
?輸出:
0 0 0
000000B0DDAFF6A4 000000B0DDAFF6A4 000000B0DDAFF6A4
? ? ? ? 從上述的輸出可以很明顯的看出引用是和被引用的實體共用用一塊空間。
1.2 常引用
? ? ? ? 常引用就是const關鍵字修飾的引用,但是我們在使用常引用是會遇到各種報錯,其實就是權限放大縮小的問題,所謂權限就是是否具有讀或者寫的權力,在C++中引用支持權限縮小但不支持權限放大。
1.2.1 權限放大
? ? ? ? 首先要說明的是c++是不支持權限放大的,如果出現(xiàn)權限放大就會出現(xiàn)報錯。(權限放大就是增加了權限,比如原本變量用const修飾只能讀不能修改,你用引用引用它時沒有使用const修飾即為可以修改,這就叫做權限放大,這是不被編譯器允許的。)
const int a = 0;//錯誤寫法int& ra = a; //變量a有const修飾符,說明a只讀不可寫入,這里沒有用const修飾,造成權限放大。//正確寫法const int& rra = a;
? ? ? ? 還有一種情況特別容易發(fā)生錯誤,而且犯錯的人常常覺得自己沒有發(fā)生權限放大,但是確確實實發(fā)生了,并且發(fā)生了報錯,這就是會發(fā)生類型轉換的場景。比如下面的場景。?
?1.2.2 權限縮小
? ? ? ? 在C++中權限縮小是被允許的,權限縮小就是比如原來的變量可讀可寫,你用一個const引用引用這個實體是完全可以的,比如:
int a = 0;const int& b = a;
1.3 使用場景
1.3.1 傳參?
? ? ? ? 傳參的一個特別典型的應用就是swap了,因為引用所引用的實體和本體共用的是一個空間,所以引用發(fā)生改變其實也就是本體發(fā)生改變。所以swap交換變量值就是一個很典型的應用。
void mySwap(int& a, int& b)
{swap(a, b);
}
int main()
{int a = 0, b = 1;cout << a << b << endl;swap(a, b);cout << a << b << endl;
}
?輸出:
01
10
1.3.2 做返回值
int& count()
{static int a = 0;a++;//...return a;
}
? ? ? ? ?但是我們在返回引用的時候要特別注意被引用對象的作用域和聲明周期,以免導致非凡的訪問,比如下面的案例:
//錯誤案例
int& add(int a, int b)
{int c = a + b;return c;
}
int main()
{cout << add(1, 2) << endl;
}
? ? ? ? 所以這里縱使編譯器返回了正確的結果甚至也沒有報錯,但它依然是一種錯誤的使用。
?1.4 傳值和傳引用的效率比較
? ? ? ? 以值作為參數(shù)或者返回類型,在傳參和返回的期間,變量不會直接傳遞實參或返回變量本身,而傳遞的是實參或者變量的一份臨時拷貝,如果需要拷貝的類型特別大的時候,效率是極低的。而傳引用是直接傳遞實參或返回變量的本身,幾乎沒有什么消耗。? ??
?1.5 引用和指針的區(qū)別
? ? ? ? 在語法概念上引用其實是一個別名沒有獨立的空間,和其引用的實體共用同一塊空間。但是在底層的實現(xiàn)上實際上是有空間的,因為引用是按照指針方式來實現(xiàn)的。我們通過引用和指針的匯編代碼就可以很容易的看出來。
????????引用和指針的不同點:
- ?引用在概念上定義一個變量的別名,指針存儲一個變量地址。
- 引用在定義的時候必須初始化,指針沒有要求。
- 引用只能引用一個實體,不能更改,指針可以在任何時候指向一個任意的同類型的實體。
- 沒有NULL引用,有NULL指針。
- sizeof(引用)是引用類型的大小,但指針始終是地址空間所占字節(jié)個數(shù)。
- 引用自增為所引用的實體自增,指針自增表示向后偏移一個類型的大小。
- 指針需要顯式解引用,引用編譯器自己處理。
- 引用比指針安全。
2. 內聯(lián)函數(shù)
?2.1 inline
? ? ? ? 以inline關鍵字修飾的函數(shù)叫做內聯(lián)函數(shù),編譯時C++會在調用內聯(lián)函數(shù)的地方展開,沒有函數(shù)建立棧幀的開銷,提升程序運行的效率。C++期望用inline去替代c語言的宏(因為宏不方便調試,會使代碼可讀性降低,可維護性差,沒有類型的安全檢查)
?2.2 特性
????????inline是一種空間換時間的做法,如果編譯器將函數(shù)當成內聯(lián)函數(shù)處理,在編譯階段,會用將函數(shù)體替換函數(shù)調用,但會讓目標文件變大。
? ? ? ? inline對于編譯器只是一個建議,不同的編譯器關于inline的實現(xiàn)機制有可能不同,一般將函數(shù)規(guī)模較小的函數(shù)不是遞歸且頻繁調用的函數(shù)采用inline修飾,否則編譯器可能會忽略inline特性。
? ? ? ? inline也不支持聲明和定義分離分離會導致鏈接錯誤,因為inline函數(shù)會被展開,沒有函數(shù)地址,如果聲明和定義分開會導致鏈接階段找不到函數(shù)的地址從而報錯。