Параметры функций C++: ссылочные и константные параметры

глубокое обучение

1. Использование ссылок в параметрах функции

\

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;
}


результат операции:

\

\

Два константных формальных параметра и фактические параметры

\

1. Константа верхнего уровня будет игнорироваться, когда фактический параметр инициализирует формальный параметр, то есть, когда формальный параметр имеет константу верхнего уровня,

Вы можете передать ему константный объект или неконстантный объект.Конечно, вы не можете записать входящий объект независимо от того, является ли он константным объектом или нет.

#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:

Нажмите здесь, чтобы узнать больше о 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("Коби Брайант",'a',s) сообщает об ошибке!

\

(2) Если в списке параметров другой функции есть (const string &s, ···)

\

И функция используется в функции

\

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

\

Ошибка! Конечно, если вы действительно хотите определить такие формальные параметры, вы также можете определить строковую переменную, стать копией s, а затем передать ее в

\

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

\

\

\

\

\

\

\

\


\