C++三大特性:封裝繼承多型。今天說說是靜態的多型——函數過載
我們先來看一段程式
int sum(int a,int b)
{
return a + b;
}
int sum1(double a,double b)
{
return a + b;
}
int main()
{
int a = 10, a1 = 10;
int b = 10.0, b1 = 10.3;
int sum = sum(a,a1);
cout<<sum<<endl;
sum = sum1(b,b1);
cout<<sum<<endl;
return 0;
}
當我們寫一個加函數的時候爲了適應不同的型別,我們要寫好幾個函數用來適應型別,但問題是寫這麼多函數,在新增新的功能的時候或者呼叫的時候如何來確定哪個函數對應的哪個型別呢?這造成了很多不必要的麻煩,因此我麼引入函數過載的概念。
函數過載是C++中非常重要的特性,那麼什麼是函數過載呢?
一組函數函數名相同,參數列表個數或者型別不同,且處於同一作用域,那麼這一組函數稱作函數過載。在呼叫的時候通過傳入形參的個數和型別來確定具體呼叫哪個函數。
我們先來舉個例子說明吧
int sum(int a,int b)
{
return a + b;
}
int sum(double a,double b)
{
return a + b;
}
int main()
{
int a = 10, a1 = 10;
int b = 10.0, b1 = 10.3;
int sum = sum(a,a1);
cout<<sum<<endl;
sum = sum(b,b1);
cout<<sum<<endl;
return 0;
}
上述的程式碼中,sum函數被過載,編譯器根據其傳入參數型別的不同選擇呼叫sum函數,用來方便程式設計師的使用。那麼爲什麼C++支援函數過載,但是C語言不支援呢?
因爲C++程式碼在編譯過程中產生函數符號的時候,是由函數名加參數列表型別組成的
而C程式碼產生符號的時候,只能由函數名來決定
函數過載的時候需要注意什麼:
1、必須在同一作用域中。
2、返回值不同的不是過載函數
我們先來簡單回顧下C語言中的const
const修飾的變數不能夠作爲左值,在初始化之後,值不能被修改
const修飾的變數可以不用初始化,但是建立之後就沒有辦法進行賦值了。
const修飾的變數不叫常數叫常變數
const修飾的變數在記憶體上是可以修改的,只是語法上不能被修改
在C++上:
const修飾的變數必須初始化,叫做常數(可用於定義陣列)。
如果初始值不是立即數那麼const修飾的值叫做常變數不叫常數
C和C++中const的區別:
const編譯的方式不同,c中const就當作一個變數來編譯生成指令的
C++中所有出現const常數名字的地方,都被常數的初始值替代了。
來看一段程式碼
int main()
{
const int a = 20;
int array[a] = {};
cout<<a<<endl;
int *p = (int *)&a;//a的記憶體已經改了
*p = 30;
cout<<a<<endl;
return 0;
}
上述程式碼中輸出結果是
20
20
爲什麼第二個a是20呢?
這就要看C和C++中的編譯方式了,C++出現const變數的地方都被常數的初始值代替
即編譯完成之後是
int main()
{
const int a = 20;
int array[20] = {};
cout<<20<<endl;
int *p = (int *)&a;//a的記憶體已經改了
*p = 30;
cout<<20<<endl;
return 0;
}
const修飾的量常出現的錯誤:
1、常數不能作爲左值
2、不能把常數的地址泄露給一個指針或者普通的參照變數
const和一級指針的結合
**const int p
可以任意指向不同的int型別的記憶體,但是不能通過指針簡介修改指向的記憶體的值
int const p
這個指針p現在是常數,不能再指向其他記憶體,但是可以通過指針解除參照修改指向的記憶體的值
int main()
{
int a = 10;
const int *p = &a;
int *p1 = &a;
int *q = p;//錯誤,把常數的地址泄露給普通指針
const int *p2 = p1;//正確
return 0;
}
總結const和指針的型別轉換公式:
int * <= const int * 是錯誤的!!!
const int * <= int * 是可以的!!!
(特別注意)const如果右邊沒有*的話const是不參與型別的
const和二級指針的結合:
int * * <= const int * * 錯誤的
const int ** <= int ** 錯誤的
int * * <= int * const * 是錯誤的
int* const * <=int * * 是可以的
下面 下麪我們來看一道面試題
int main()
{
int a = 10;
const int *p = &a;
int *q = p;
return 0;
}
面試官會問你:p裏面存的是a的地址。把p給q,q裏面也是a的地址,那麼可以通過q修改a的值,那麼這個語句是否正確?
首先要明確,這個題和a沒有任何關係,第二行的程式碼轉換就是錯誤的,跟a沒有任何關係。
C++參照和指針的區別
1、左值參照和右值參照
2、參照的範例
解除參照:通過當前記憶體存放的地址找到相應的儲存單元
參照是一種更安全的指針
1、參照必須初始化的,指針可以不初始化
2、參照只有一級參照,沒有多級參照,指針可以有一級指針,也可以有多級指針。
const ,一級指針,參照的結合參照
寫一句程式碼,再記憶體的0x0018ff44出寫一個4位元組的整數
int * const & p = (int *)0x0018ff44
參照方式的返回值 整個函數呼叫,參照變數 暫存器帶回返回值的地址,使用時自帶解除參照
不能放回區域性變數的地址或者參照