1. 程式人生 > >C++函式傳參:引用和const引數

C++函式傳參:引用和const引數

一  在函式傳參中使用引用

1.使用例子:

#include<iostream>
using namespace std;
void reset(int &i){//引用傳參
	i=0;
}
void reset(int *i){//指標傳參
	*i=0;
}
int main(){
	
	int a=10,b=24,c=8;
	int &d=b;
	reset(a);cout<<a<<endl;
	reset(d);cout<<d<<endl;
	reset(&c);cout<<c<<endl;
	return 0;
} 

上面結果執行均是0。

2. 函式傳參使用引用的好處:

(1)避免拷貝:

拷貝大的類型別物件或者容器物件是不值得提倡的。

也有可能有些類型別就不支援拷貝,此時函式只可通過引用形參訪問物件。

(2)可以返回更多資訊:

例如:下用cnt傳回所找字元出現個數。

#include<iostream>
#include<string>
using namespace std;
string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt){
	auto first=s.size();
	cnt=0;
	for(decltype(first) i=0;i!=s.size();++i){
		if(s[i]==c){
			if(first==s.size())
				first=i;
			cnt++;
		}
	}
	return first;
}
int main(){
	int first;
	string::size_type occurs=0;
	cout<<"第一次出現a位置:"<<FindFirstOccur("kobe bryant",'a',occurs)<<endl;
	cout<<"出現的次數:"<<occurs<<endl;
	return 0;
}

執行結果:


二 const形參和實參

1. 實參初始化形參時會忽略頂層const,即是說,形參有頂層const的時候,

傳給它常量物件或者非常量物件均可以,當然對傳進來的不管是不是const物件,都不能寫。

#include<iostream>
using namespace std;
void test(const int i){
	
}
int main(){
	const int a=0;
	int i;
	test(a);
	test(i);
	return 0;
}

儘管在C++中可以允許函式名字相同但通過形參列表的不同區分,

但是由於形參頂層const被忽略,故不能做一下貌似對的寫法:

#include<iostream>
using namespace std;
void test(const int i){
	
}
void test(int i){

}
int main(){
	const int a=0;
	int i;
	test(a);
	test(i);
	return 0;
}

會顯示重複定義!

2. 我們要知道一些const方面的細節:

容易理解:

#include<iostream>
#include<string>
using namespace std;
void reset(int &i){
	i=0;
}
void reset(int *i){
	*i=0;
}

string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt){
	auto first=s.size();
	cnt=0;
	for(decltype(first) i=0;i!=s.size();++i){
		if(s[i]==c){
			if(first==s.size())
				first=i;
			cnt++;
		}
	}
	return first;
}
int main(){
	int i=24;
	const int *p=&i;//正確,且不能通過p改變i,底層const!
	const int &r=i;//正確,且不能通過r改變i
	const int &r2=24;//正確!
//	int *p2=p;//錯誤!
//	int &r3=r;//錯誤!
//	int &r4=42;//錯誤!
	
	const int a=i;
	string::size_type s=0;
	reset(&i);//void reset(int *i)
//	reset(&a);//錯誤!不能用指向const int物件的指標初始化int *
	reset(i);//void reset(int &i)
//	reset(a);//錯誤!不能將普通引用繫結到const物件
//	reset(42);//錯誤!
//	reset(s);//錯誤!型別不匹配,s是無符號型別
	FindFirstOccur("kobe bryant",'a',s);
	return 0;
} 

3. 使用常量引用

若函式不改變形參,儘量將形參定義為常量引用,可避免兩個問題:

(1)如在上述函式

string::size_type FindFirstOccur(const string &s,char c,string::size_type &cnt)

中,改為

string::size_type FindFirstOccur(string &s,char c,string::size_type &cnt)

則對於呼叫

FindFirstOccur("kobe bryant",'a',s)報錯!

(2)如果在另一個函式形參列表中有const string &s,·····

且函式中裡面使用了函式

string::size_type FindFirstOccur(string &s,char c,string::size_type &cnt)

報錯!當然如果真要如此定義形參,也可以定義一個string變數,成為s副本,再傳給

FindFirstOccur(string &s,char c,string::size_type &cnt)