第6章 6.3 返回类型和return语句
6.3.1 无返回值函数
**没有返回值的return语句只能用在返回类型是 void 的函数中。**返回 void 的函数不要求非得有return语句,因为这类函数的最后一句后面会隐式地执行return.
6.3.2 有返回值函数
只要函数的返回类型不是void,则该函数的每条return语句必须返回一个值。
return语句返回值的类型必须与函数的返回类型相同,或者能隐式地转换成函数的返回类型。
【值是如何被返回的】
返回一个值的方式和初始化一个变量或形参的方式完全一样:返回的值用于初始化调用点的一个临时量,该临时量就是函数调用的结果。
同其他引用类型一样,如果函数返回引用,则该引用仅是它所引对象的一个别名,例如:
// 比较两个字符串,返回较短字符串的引用
// 形参和返回类型都是const string的引用
// 无论是调用函数还是返回结果都不会真正拷贝string对象
const string &cmp(const string &a, const string &b) {
return a.size() < b.size() ? a : b;
}
【不要返回局部对象的引用和指针】
函数完成后,它所占的存储空间也随之被释放掉。因此,函数终止就意味着局部变量的引用将指向不再有效的内存区域。例如:
// 该函数的两个return语句都指向了不再可用的内存空间
const string &func() {
string a = "hehe";
if(!a.empty()) {
return "haha"; // 错误:"haha"是一个局部临时变量
}
return a; // 错误:返回局部对象的引用
}
【列表初始化返回值】
C++11新标准规定,函数可以返回花括号包围的值的列表。类似于其它返回结果,此处的列表也用来对表示函数返回的临时量进行初始化。如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定。
例如:
vector<int> func(int i) {
if(i > 1) {
return {2, 3, 4};
}
return {1};
}
6.3.3 返回数组指针
因为数组不可以被拷贝,所以函数 不能返回数组,但 可以返回数组的指针或引用。
【使用类型别名】
要想定义一个返回数组的指针或引用的函数,最直接的方法就是使用 类型别名。例如:
typedef int arra[10]; // arra是一个类型别名,它表示的类型是含有10个int的数组
using arra = int [10]; // arra的等价声明
arra* func(int i); // 函数func返回一个指向含有10个int的数组的指针
【声明一个返回数组指针的函数】
要想定义一个返回 数组指针 的函数,则 数组的维度必须跟在函数名字之后。然而,函数的形参列表也跟在函数名字后面且形参列表应先于数组的维度。因此,返回数组指针的函数的形式为:
Type (*function(parameter_list)) [dimension]
// Type:元素的类型
// dimension:数组的大小
举个例子:
int (*func(int i))[10];
可以按照以下的顺序来逐层理解该声明的含义:
(1)func(int i)
表示调用 func
函数需要一个 int 类型的参数;
(2)(*func(int i))
意味着可以对函数调用的结果执行解引用操作;
(3)(*func(int i)) [10]
表示解引用得到一个大小是10的数组;
(4)int (*func(int i)) [10]
说明数组的元素是int 类型。
【使用尾置返回类型】
在 C++11 新标准中规定可以使用 尾置返回类型。任何函数的定义 都可以使用尾置返回,这种形式对于返回类型比较复杂的函数最为有效,例如返回类型是数组的指针或数组的引用。
位置返回类型跟在形参列表后面,并以 -> 符号开头。为了表示函数真正的返回类型跟在形参列表之后,因此需要在本该出现返回类型的地方放置一个 auto。例如:
// func函数接受一个int类型的形参
// 返回一个指针,该指针指向一个含有10个整数的数组
auto func(int i) -> int(*)[10];
【使用 decltype】
我们还可以使用 decltype 关键字来声明返回类型。
【注意】decltype 并不负责把数组类型转换成对应的指针,所以 decltype 的结果是一个数组。
例如:
int a[] = {1, 2 ,3};
int b[] = {4, 5 ,6};
// decltype(a)的结果是一个整型数组
decltype(a) *func(int i) {
return (i % 2) ? &a : &b; // 返回一个指向数组的指针
}