2)在有的时候我们需要向函数传递大型对象,需要使用引用形参,如果直接使用复制实参的形式可以,但是它的效率太低了,甚至有些对象是无法复制的。但是使用引用形参时,我们不希望函数改变了实参传入的值,我们就可以使用const来限定形参。下面程序用来判断哪个字符串更长,明显我们不希望函数会改变字符串的内容,我们就可以用const引用型的形参。
bool isLonger(const string &s1, const string &s2) { return s1.size() > s2.size(); }
所以,如果使用引用形参的惟一的目的是避免复制实参时,则应将形参定义为const引用。
3)在使用引用形参函数时,有两点值得注意:
不要用const限定的实参或字面值来调用非const引用形参函数。因为这样函数内,可以改变实参的值,这不合法。
非const引用形参只能与完全同类型的非const对象关联。
4)传递指向指针的引用
如下有下面的程序:
void swap(int* &v1, int* &v2) { int* temp = v2; v2 = v1; v1 = temp; } int main() { int a = 10,b = 20; int* p1 = &a, *p2 = &b; swap(p1,p2); return 0; }
上面的程序依然不能改变a与b的值,但是它改变了p1与p2的值,现在p1指向了b,而p2指向了a。
3,其他类型的形参
1)vector和其他类型的形参:一般在这种类型作为形参时,为了避免复制应该考虑形参声明为引用类型。C++程序员倾向于传递容器中需要处理的元素的迭代器来传递容器。
2)数组形参:由于数组不能复制,所以不能直接编写数组类型的形参函数,一般通过传递指向数组的元素的指针来处理数组。值得注意的是在通过引用传递数组时,在调用函数时形参与实参的类型要匹配。
void printValues(int (&ar)[10]); int main() { int i = 0, j[2] = { 0, 1 }; int k[10] = {0,1,2,3,4,5,6,7,8,9}; printValues(i); //error int不能初始化 int(&)[10] printValues(j); //error int[2] 不能初始化 int(&)[10] printValues(k); // ok return 0; }
二、函数的返回值
1)没有返回值
很多函数并没有返回值,尤其是现在C++风格,习惯于把需要的结果作为引用形参。这类型函数一般没有return语句,有时候有return是使函数中途中断执行。
2)返回非引用类型
这种情况在函数调用处,程序会用一个临时变量复制函数的返回值。
3)返回引用
当函数返回引用类型时,并没有复制返回值。相反,返回的是对象本身。