重溫《C++ Primer》筆記九 const形參小結

首先,形參大致可以分爲三種:非引用形參、引用形參和指針類型形參。


一、非引用形參

在傳遞參數的時候,不論是所謂的傳值還是傳址,實際上都是實參值到形參值的複製,其中的區別只是複製的是普通對象還是引用對象而已。對於非引用形參,通過參數傳遞之後,形參是實參的一個副本,而非引用形參使得複製後形參與實參並沒有任何關聯,因此,在函數中對形參的任何操作將不會影響到實參的值,因此,不論實參是變量還是常量,形參的操作是基於副本的,將不受任何的限制。如下例子:

void func1(int num)
{
	int value1 = num;
}

void func2(const int num)  //const形參
{
	int value1 = num;
}
void main()
{
	int num1 = 1;
	const int num2 = 2;
	func1(num1);
	func1(num2);  //ok,將const對象傳遞給非const形參
	func2(num1);
	func2(num2); 

這裏,儘管實參是const常量,仍然可以傳遞給非const形參,因爲形參操作的是實參的副本,並不直接訪問const實參,因此,不論實參是不是const常量都與形參無關了。

對於編譯器,儘管func2的形參是const,但是編譯器將func2的定義視爲其形參被聲明爲普通的int一樣。


二、對於引用形參

首先需要知道的是:引用是一個特殊指針常量,編譯器自動對其進行間接訪問。因此,對於引用的操作便只有一種:對此特殊指針常量的間接訪問。因此,儘管引用形參僅僅只是實參地址的副本,但是引用的操作只是間接訪問,從而導致必須影響到與引用關聯的內存區域(實參對象)了。另外一點,我們常說的const引用指的是指向const對象的引用。所以,如果實參爲const對象,則必須要求形參爲const類型。
<span style="font-size:14px;">void func1(int &num)
{
	int value1 = num;
}

void func2(const int &num)  //const引用形參
{
	int value1 = num;
}
void main()
{
	int num1 = 1;
	const int num2 = 2;
	func1(num2);  //error,不能將const對象傳遞給非const形參</span>
上面的func1函數的形參是const,這使得在func1函數中能夠自由訪問形參的值,如果傳遞的實參爲const,則會錯誤訪問const對象。錯誤提示如下:


三、對於指針形參

引用是指針的一個特例。指針的操作有兩種:1、直接訪問,這隻會改變地址值;2、間接訪問,會改變與地址關聯的內存區域。在傳遞參數的時候,形參將得到一個實參的複製,即地址形參將得到一個地址實參的副本。如果是在地址值的級別上訪問,則不會影響到實參的內容。因此,在形參地址的級別上加上const將不會有任何的作用,這與非引用形參一樣。如果是在地址關聯的對象的級別上訪問,則會影響到實參的內容,因此,如果在地址關聯的對象上加上const(即聲明爲指向const對象的指針),則與引用類似了。
對於指針形參,能夠影響到實參的只有與指針關聯的內存區域,因此,只有在指針形參所指向的對象是否爲const纔會影響到實參。

總結:對於編譯器而言,並沒有真正的const形參,const非引用形參與普通形參將被編譯成同一個函數,即普通形參函數。而對於指針常量形參,*const形參將於*形參被編譯成同一個函數,即*形參函數。只有在引用與指針形參中與引用與指針關聯的對象上加上const才與不加const形參不同。(這在函數重載的時候非常有用,前兩種算作函數重定義,而第三種纔算是函數重載)


發佈了68 篇原創文章 · 獲贊 42 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章