C++----局部静态对象和函数
2017-05-24 15:59
381 查看
局部静态对象
某些时候,有必要令局部变量的生命周期贯穿函数调用之后的时间。可以将局部变量定义成static类型从而获得这样的对象。局部静态对象(local static object)在程序的执行路径第一次经过对象定义语句是初始化,并且直到程序终止才被销毁,在此期间及时对象所在的函数结束执行也不会对它有影响。举个例子,下面的函数统计它自己被调用了多少次:
size_t count_calls(){ static size_t ctr = 0;//调用结束后,这个值仍然有效 return ++ctr; } int main(){ for(size_t i = 0; i != 10; ++i) cout << count_calls() << endl; return 0; }
函数参数传递
和其他变量一样,形参的类型决定了形参和实参的交互方式。如果形参是引用类型,它将绑定到对应的实参是,否则,将实参的值拷贝后赋给形参。void reset(int &i){ i = 0; } int j = 42; reset()j; cout << "j=" <<j <<endl; //输出j=0
使用引用避免拷贝
拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型根本就不支持拷贝操作。当某种类型不支持拷贝操作时,函数只能通过引用形参访问该类型的对象。比如,我们准备编写一个函数比较两个string对象的长度。因为string对象可能会非常长,所以应该避免直接拷贝它们~
bool isshorter(const string &s1, const string &s2){ return s1.size() < s2.size(); }
数组引用形参
C++语言允许将变量定义成数组的引用,基于同样的道理,形参也可以是数组的引用。此时,引用形参绑定到对应的实参上,也就是绑定到数组上:void print(int ($arr)[10]){ for(auto elem:arr) cout <<elem<<endl; }
&arr两端的括号不能少哟。这表示arr是具有10个整数的整型数组的引用~(这里就能限定数组的大小了)
int i = 0, j[2]={0,1}; int k[10] = {0,1,2,3,4,5,6,7,8,9}; print(&i); //wrong print(j); //wrong print(k); //right
传递多维数组
在C++语言中实际没有真正的多维数组,所谓多维数组其实是数组的数组。和所以数组一样,当将多维数组传递给函数时,真正传递的是指向数组首元素的指针。因为我们处理的是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针。数组第二维(以及后面所以维度)的大小都是数组类型的一部分,不能省略:
void print(int (*matrix)[10]. int rowSize){/*...*/}
再次强调,*matrix两端括号不可少~
int *matrix[10]; //10个指针构成的数组 int (*matrix)[10]; //指向含有10个整数的数组的指针
我们也可以使用数组的语法定义函数,此时编译器会一如既往地忽略掉第一个维度,所以最好不要把它包括在形参列表内:
//等价定义 coid print(int matrix[][10], int rowSize){/*...*/}
不要返回局部对象的引用或指针
函数完成后,它所占用的存储空间也随之被释放掉。因此,函数终止意味着局部变量的引用将指向不再有效地内存区域://严重错误:这个函数试图返回局部对象的引用 const string &manip(){ string ret; if(!ret.empty()) return ret; //错误:返回局部对象的引用; else return "Empty"; //错误:“Empty”是一个局部临时量 }
列表初始化返回值
C++11新标准规定,函数可以返回花括号包围的值的列表。类似其他返回结果,此处的列表也用来对表示函数返回的临时量进行初始化。如果列表为空,临时量执行值初始化;否则,返回的值由函数的返回类型决定。vector<string>process(){ //... //expected 和 actual是string对象 if(expected.empty()) return {}; else if (expected == actual) return {"functionX","okay"}; else return {"functionX",expected,actual}; }
如果函数返回的是内置类型,则花括号包围的列表最多包含一个值,而且该值所占空间不应该大于目标类型的空间。如果函数返回的是类类型,有类本身定义初始值如何使用。
返回数组指针
因为数组不能被拷贝,所以函数不能返回数组。不过,函数可以返回数组的指针或引用。这个比较麻烦,又一个简单的办法~就是使用类型别名
typedef int arrT[10]; //arrT是一个类型别名,它表示的类型是含有10个整数的数组 using arrT = int[10]; //arrT的等价声明 arrT* func(int i); //func返回一个指向含有10个整数的数组的指针
如果不用别名,我们来看看怎么办
我们声明指向数组的指针是这样声明的:
int (*p2)[10];
同理我们也这样声明函数
int (*func(int i))[10];
可以按照以下的顺序来逐层理解该声明的含义:
func(int i )表示调用func函数时需要一个int类型的实参
(*func(int i))意味着我们可以对函数调用的结果执行解引用操作
(*func(int i))[10]表示解引用将得到一个大小是10的数组
int (*func(int i))[10]表示数组中的元素是int类型
相关文章推荐
- C++ 学习笔记(6)函数、局部静态对象、重载函数、内联函数、constexpr函数、调试帮助、函数匹配、函数指针
- 深度探索C++对象模型之:成员函数语义学--静态成员函数
- 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用 (转自effective c++ second edition)
- C++中的局部静态对象
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- 关于C++函数返回局部对象的详细分析
- C++之全局对象,局部对象,静态局部对象
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- C++第七周任务【任务1】含有静态数据成员和成员函数的Time类:类中所有的对象共有的数据
- C++中的数组和局部静态对象 (转载)
- 深度探索C++对象模型之局部静态对象
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题
- c++返回函数局部对象的引用
- C++静态成员函数不能声明为const、volatile、virtual的原因 与 C++的对象模型
- C/C++函数中局部对象的构造与析构时机
- 静态内存;堆内存;函数局部栈内存 demo程序(摘自C++程序员求职关键路径)
- C++之局部对象(自动对象和静态局部对象)
- Self Summary: C++函数返回引用和指针的问题,局部对象与new对象的问题