推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习
1.我们不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。
2.数组第二位(以及后面所有维度)的大小都是数组类型的一部分,不能省略。
3.如果函数的实参数量未知但是全部实参的类型都相同,我们可以使用initializer_list类型的形参。
initializer_list;//类型定义在同名的头文件中:
initializer_list<T> lst; //默认初始化:T类型元素的空列表
initializer_list<T> lst{a,b,b...}; //lst的元素数量和初始值一样多;
lst的元素时对应初始值的副本;列表中的元素是const
lst2(lst),lst2 = lst; //拷贝或赋值一个initializer_list对象不会拷贝列表中的元素;拷贝后,原始列表和副本共享元素
lst.size(); //列表中的元素数量
lst.begin(); //返回指向lst中首元素的指针
lst.end(); //返回指向lst中尾元素下一位置的指针
4.和vector一样,initializer_list也是一种模板类型。定义initializer_list对象时,必须说明列表中所含元素的类型:
initializer_list<string> ls; //initializer_list的元素类型是string
initializer_list<int> li; //initializer_list的元素类型是int
和vector不一样的是,initializer_list对象的元素永远是常量值,我们无法改变initializer_list对象中元素的值。
void error_msg(initializer_list<string> il)
{
for(auto beg = il.begin();beg != il.end();++beg)
cout<<*beg<< ‘ ’;
cout<<endl;
}
//假设expected和actual是string对象
if(expected != actual)
error_msg({“functionX”,expected,actual}); //括号里有大括号别忘了!!!!
else
error_msg({“functionX”,”okay”}); //括号里有大括号别忘了!!!!
5.返回局部对象的引用是错误的;同样返回局部对象的指针也是错误的。一旦函数完成,局部对象被释放,指针将指向一个不存在的对象。
6.引用返回左值。函数的返回类型决定函数调用是否是左值。调用一个返回引用的函数得到左值,其他返回类型得到右值。可以像使用其他左值那样来使用返回引用的函数的调用,特别是,我们能为返回类型是非常量引用的函数的结果赋值:
char& get_val(string& str , string::size_type ix)
{
return str[ix]; //get_val假定索引值是有效的
}
int main()
{
string s(“a value”);
cout<<s<<endl; //输出 a value
get_val(s,0)=’A’; //将s[0]的值改为A
cout<<s<<endl; //输出A value
return 0;
}
如果返回类型是常量引用,我们不能给调用的结果赋值,这一点和我们熟悉的情况是一样的。
7.函数可以返回花括号包围的值的列表。类似于其他返回结果,此处的列表也用来对表示函数返回的临时量进行初始化。如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定。
如果函数返回的是内置类型,则花括号包围的列表最多包含一个值,而且该值所占空间不应该大于目标类型的空间。如果函数返回的是类类型,由类本身定义初始值如何使用。
8.cstdlib头文件定义了两个预处理量,我们可以使用这两个变量分别表示成功与失败:EXIT_FALLURE,EXIT_SUCCESS 因为他们是预处理变量,所以既不能在前面加上std::,也不能在using声明中出现。
9.因为数组不能被拷贝,所以函数不能返回数组。不过,函数可以返回数组的指针或引用。虽然从语法上来说,要想定义一个返回数组的指针或引用的函数比较烦琐,但是有一些方法可以简化这一任务,其中最直接的方法是使用类型别名:
typedef int arrT[10]; //arrT是一个类型别名,他表示的类型是含有10个整数的数组
using arrT = int[10]; //arrT的等价声明
arrT* func(int i); //func返回一个指向含有10个整数的数组的指针
10.要想在声明func时不适用类型别名,我们必须牢记被定义的名字后数组的维度:
int arr[10]; //arr是一个含有10个整数的数组
int *p1[10]; //p1是一个含有10个指针的数组
int (*p2)[10] = &arr; //p2是一个指针,它指向含有10个整数的数组
和这些声明一样,如果我们想定义一个返回数组指针的函数,则数组的维度必须跟在函数名字之后。然而,函数的形参列表也跟在函数名字后面且形参列表应该优先于数组的维度。因此,返回数组指针的函数形式如下所示:
Type (*function(parameter_list))[dimension]
类似于其他数组的声明,Type表示元素的类型,dimension表示数组的大小。(*function(parameter_list))两端的括号必须存在,就像我们定义p2时两端必须有括号一样。如果没有这对括号,函数的返回类型将是指针的数组。
举个例子,下面这个func函数的声明没有使用类型别名:
func(int i)表示调用func函数时需要一个int类型的实参。
(*func(int i))意味着我们可以对函数调用的结果执行解引用操作。
(*func(int i))[10]表示解引用func的调用将得到一个大小是10的数组。
int (*func(int i))[10]表示数组中的元素是int类型