C++中函数的用法小结
作者:网络转载 发布时间:[ 2014/2/27 9:47:56 ] 推荐标签:函数 C++ 定义 参数
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)返回引用
当函数返回引用类型时,并没有复制返回值。相反,返回的是对象本身。
在返回引用这种情况下,注意不要返回局部变量的引用,因为局部变量在函数体内定义,当函数执行完后销毁了,所谓的引用也没有意义了。同理,不要返回指向局部变量的指针。
三、重载函数
出现在相同作用域中的两个函数,如果具有相同的名字而形参不同,则称为重载函数。
1)注意区分函数重载与重复声明
有些看起来不同的形参,本质是相同的。下面代码中的都是重复声明的例子
typedef double newDouble;
int func(double i);
int func(newDouble i); // 没有新类型
int func1(int, int = 1); //只是提供默认参数
int func1(int ,int);
int func2(int);
int func2(const int); //对于普通非引用形参用cosnt修饰是没有意义的
2)重载与作用域
局部声明的函数,将屏蔽所有全局作用的同名函数。下面例子显示,即使全局作用的函数更加匹配调用的实参类型,但是仍然调用的是局部的函数。
void print(int);
int main()
{
void print(double);
print(42);
return 0;
}
上面程序中,将调用void print(double)函数,虽然42是int型。
3)重载确定的三个步骤
如果定义了众多的函数重载,将存在函数调用到底与哪个重载函数相匹配的问题。我们通过下面的示例代码来说明问题:
void f(); // 1
void f(int);// 2
void f(double);// 3
void f(int, int);// 4
void f(double, double);// 5
第一步:确定候选函数
假如我们调用f(4.2),那么先找到同名函数,并且在作用域内可见,上面例子中5个函数都满足。
第二步:选择可行的函数
必须满足2个条件:一是函数形参与该调用实参个数相同;第二,每个实参的类型必须与对应的类型匹配,或者可以被隐式转换为对应的形参类型。这里我们再调用f(4.2)时,排除了1、4、5号函数,只剩下2与3。其中2号函数可以通过类型转换来满足。
第三步:寻找佳匹配
在经过第二步确定后,剩下2与3函数,那么2需要进行类型转换,显然3是佳匹配了。
但是如果这样调用f(42,4.2)。这时候会出现二义性,编译器将提示。
还有一种要注意的是有默认参数的函数,比如我们定义6号函数为void f(double,int =1);那么在调用f(4.2)时会有二义性。
可基于函数的引用形参是指向const对象还是指向非const对象实现函数重载。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11