C++簡明分析講解引用與函數提高及重載
詳解引用
引用的基本使用
語法:數據類型 &新變量名 =原來變量名
作用:給變量起別名
註意事項:
1、引用必須初始化
2、一旦初始化就不能更改(具體原因在下面引用本質上會講到)
示例:
int a = 10; int c = 20;
如果寫 int &b;
這是錯誤的,沒有初始化引用,編譯器不知道b指向的地址。
所以這樣寫 int &b=a;
那麼現在b是a 的別名,他們的地址相同,存放的數據也都一樣。這時如果寫 b=c;我們不會認為 b是c的別名,隻會認為是把c的值賦給瞭b,當然也賦給瞭a
引用做函數參數
這是引用最為方便和精辟的地方瞭,直接代替指針來進行引用傳遞,我們舉個最為經典的例 子:swap交換函數.
void swap(int &x,int &y) { int t = a; a = b; b = t; cout << "swap03 a =" << a << endl; cout << "swap03 b =" << b << endl; } int main() { int a = 10, b = 20; /*值傳遞形參不能修飾實參 地址傳遞可以修飾實參*/ swap(a, b);//引用做函數參數也可以修飾實參 }
這裡主函數傳的實參是a,b 形參是int &x,int &y;
不就是int &x= a, int &y= b
嗎,x和a地址相同,y和b地址相同,x和y的變化必會導致a,b的變化,因此屬於地址傳遞,不會令編譯器產生副本,節省空間的同時,代碼也更簡潔。
引用做函數返回值
我們知道函數語法第一個就要寫函數返回值類型,在數據類型後加上&符號,就可以返回該函數的引用,有的也叫返回函數的地址,其實意思都一樣,隻是叫法不同罷瞭。
註意事項:
1、不要返回局部變量的引用
2、返回函數的引用可以作為左值
示例:
#include<iostream> using namespace std; int& func1() { int a = 10;//局部變量放在四區中的棧區,返回後會被編譯器自動銷毀 return a; } int& func2() { static int a = 10; return a; } int main() { int& ref1 = func1(); int& ref2 = func2(); cout << "a =" << ref1 << endl; cout << "a =" << ref1 << endl;//亂碼 cout << "a =" << ref2 << endl; func2() = 1000;//如果函數的返回值是引用,那這個函數調用可以作為左值 cout << "a =" << ref2 << endl; }
func1函數開辟在棧區,返回的引用會被編譯器自動釋放掉,main函數中我用&ref1作為func1的引用返回,並輸出ref1的值,不出意外,第二次輸出的時候會出現亂碼,其實就是ref的新地址,func1返回的地址已經被釋放掉,第一次能輸出是因為編譯器做出瞭保留。func2雖然也是開辟在棧區,但是a 的地址卻是放在瞭全局區,由操作系統自動釋放,所以返回func2的引用不會被編譯器釋放,而且可以作為左值變化數據,最後一個cout結構必當是1000,附上結果圖。
常量引用
這個就好理解瞭,就是傳參的時候加上const關鍵字,防止誤操作
示例:
//打印數據函數
void showData(const int& a) {
//a=100; 這裡不能做出修改,防止誤操作
cout << "a=" <<a<< endl;
}
引用的本質
引用的本質是一個指針常量
編譯器發現是“引用”自動將int &ref=a;
轉變為 int *const ref=&a;
並且再給 ref賦值時,自動解引用 ref=100 改為 *ref = 100
示例:
void fun1(int &ref) //自動轉變為 int *const ref=&a
{
ref = 100; //轉換成*ref=100
}
C++推薦使用引用,因為引用的本質是指針常量,但是有關指針的操作編譯器都幫我們做瞭
函數提高
學習C很快就會接觸函數瞭,這裡主要講你少見的函數形式來做一個函數提高
函數默認值
語法:返回類型值 函數名 (形參=默認值){}
註意事項
1、如果某個位置已經有默認參數,那麼從這個位置開始從左往右都要有默認值
2、聲明和實現隻能有一個有默認參數,如果聲明的時候給瞭形參默認值,那麼下面對函數的實現就不能再給該形參默認值
示例:
int fun1(int a, int b, int c=50); int fun1(int a, int b, int c) { return a + b + c; } int main() { cout << fun1(10,30) << endl; }
這裡cout的結果我們都能猜到是90;如果我們修改代碼給形參b默認值,而不給c默認值,就會違反第一個註意事項,這時給c也默認值就解決問題瞭。
函數占位參數
語法:返回值類型 函數名(數據類型){}
占位參數可以有默認參數:
void fun2(int a,int=20)
{
cout << a<<"is this is fun2" << endl;
}
調用:
fun2(10);
結果:
10is this is fun2
函數重載及註意事項
函數重載需要函數都在一個作用域下
函數名相同,提高復用性
函數參數類型不同 或者 個數不同 順序不同
#include<iostream> using namespace std; void func() { cout << "func 的調用" << endl; } void func(int a) { cout << "func(int a)的調用" << endl; } void func(double a) { cout << "func(double a)的調用" << endl; } void func(int a, double b) { cout << "func(int a,double b)的調用" << endl; } void func(double b,int a) { cout << "func(doubel b,int a)的調用" << endl; } //函數返回值不可以做重載條件 int main() { func(); func(10); func(12.3); func(10,20.1); func(30.1,20); }
這裡寫五個func函數,四個重載,並配上提示助理解,輸出結果如下:
函數重載註意事項:
1、引用可作為重載的條件
void funct(int& a) { cout << "funct(int &a)的調用" << endl; } void funct(const int& a) { cout << "funct(const int &a)的調用" << endl; }
調用方法:int a = 10; funct(a); funct(20);
重載時加上const 關鍵字就相當於是一個常量,調用的時候直接寫入數據即可。
2、函數重載碰到默認參數
void func2(int a,int b=10) { cout << "func(int a,int b)的調用" << endl; } void func2(int a) { cout << "func(double a)的調用" << endl; }
這裡調用func2方法必然會報錯,因為兩個函數發生瞭重載,而且調用方法一致,都是
func2(數值);
那麼就會產生二義性,編譯器無法識別調用的是哪個重載的方法。
到此這篇關於C++簡明分析講解引用與函數提高及重載的文章就介紹到這瞭,更多相關C++引用與函數提高內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- C++ 引用與內聯函數詳情
- C++引用的詳細解釋
- C++示例分析內聯函數與引用變量及函數重載的使用
- C++深入淺出講解內存四區與new關鍵字的使用
- C++ 內存分區模型的使用(代碼區、全局區、棧區、堆區、new)