C++----局部静态对象和函数
来源:互联网 发布:免费的看书软件 编辑:程序博客网 时间:2024/05/29 08:01
局部静态对象
某些时候,有必要令局部变量的生命周期贯穿函数调用之后的时间。可以将局部变量定义成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); //wrongprint(j); //wrongprint(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++----局部静态对象和函数
- c语言之静态局部变量,静态全局变量和静态函数
- [c++]非局部静态对象初始化顺序
- C++中的数组和局部静态对象
- C++中的数组和局部静态对象
- C++处理函数局部静态类对象的构造和析构
- 全局变量、局部变量、静态局部变量、静态全局变量、外部变量、外部函数和静态函数
- 全局对象和全局静态、局部静态析构顺序
- 非局部静态对象
- 局部静态对象
- 再认识局部静态对象
- C++之局部对象(自动对象和静态局部对象)
- C/C++——全局变量、局部变量、静态全局变量和静态局部变量
- [C++] 静态局部变量
- C++中的数组和局部静态对象 (转载)
- C++ 全局对象 全局变量和局部变量 静态变量
- C++ 全局对象 全局变量和局部变量 静态变量
- C++中的局部静态对象
- Adaboost的几个人脸检测网站
- Docker 使用总结
- springMVC学习笔记
- 关于sql语句的一些整理(下)
- 1045. 快速排序(25)
- C++----局部静态对象和函数
- (95)宏库UI
- 软件架构模板
- Linux_Nginx 安装笔记
- curl 调用接口报错 Protocol http not supported or disabled in libcurl
- android中如何实现进入一个界面不做任何动作过10秒钟(有操作从新计时)自动跳转到待机activity,点击待机界面回到原来的界面
- 龙芯推出新一代处理器 离Intel还有多大差距
- 40个Java多线程问题总结
- IOS 设备信息和系统信息获取大全