2.4使用局部静态对象
2.2节的fibon_seq()函数每次被调用时,便计算出Fibonacci数列(元素个数由用户指定)。
fibon_seq(24);
fibon_seq(8);
fibon_seq(11);
第一次调用就已经计算出第二次,第三次调用所需要计算的值。
倘若第四次 fibon_seq(32)需要计算32个元素,而我们有能力将每次调用所计算出来的元素值储存起来,那么我们在第四次调用中我们实际上也只需要再计算#25~#32这些元素值。
而这里面我们又不能把那个vector定义在file scope里面 尽量不要用file scope 因为file scope对象会打乱不同函数之间的独立性,使他们难以理解。
本例子的另一解法是使用局部静态对象()。这意味着什么呢?和局部非静态对象不同的是,局部静态对象所处的内存空间,即使在不同的函数调用过程中,依然存在。
比如说,我使用一个空的vector,在我们使用的时候按照需求插入必要的元素。比如说使用push_back()会将数值放在vector末端。
静态局部对象底层逻辑是什么
局部对象,其生命在作用域结束的时候,析构函数会被自动地调用,即对象自动被清理,很显然,局部对象被存放在栈中。
静态局部对象(static local object),其生命在作用域结束之后依然存在,即此时的对象析构函数依然存在,即此时对象的析构函数并不会被调用,直到整个程序结束。
2.5声明Inline函数
2.6提供重载函数(function overloading)
参数列表不相同的两个或者多个函数,可以拥有相同的函数名称。
编译器怎么知道用哪个?它会将调用者提供的实参和每个重载函数进行对比,找出最合适的。
编译无法根据返回类型来区分两个具有相同名称的函数。比如:
ostream& display_message(char cn);
bool display_message(char cn);
为什么? 因为我们在调用函数的时候,编译器不知道返回类型,也就是不知道调用操作究竟想要调用哪个函数。
2.7定义并使用模板函数
2.8函数指针带来更大的弹性
const vector* fibon_seq(int size) 类似于fibon_seq(),我们定义五种数列类型:
例如:const vector* lucas_seq(int size) 这个函数的作用是计算出到数列某个位置的元素大小。 比如斐波那契数列是 1 1 2 3 5 8 这个函数的参数是6 那么我们就把这六个数计算出来存在static vector里。
那么有一个函数是fibon_elem() 这个函数有一个特点,就是它需要调用 XXX_seq()函数
比如说fibon_elem()这个函数
bool fibon_elem(int pos,int &elem)
{const vector *pesq = fibon_seq(pos);} 这里面要根据pos给出的位置调用vector指针。
但是我们也必须针对所有数列提供六个不同的 XX_elem()函数吗 ,显然太麻烦了。
这时候我们就可以利用到函数指针 他必须指明它所指的函数返回类型和参数列表。为了将函数视作一个指针 我们必须用小括号改变优先级
const vector* (seq_ptr)(int);
这时候我们把fibon_elem()重新来过。
bool seq_elem(int pos,int &elem,const vector(*seq_ptr)(int)){
const vector *pesq = seq_ptr(pos);
在这种情况下 我们想要写一个显示循环 在每次迭代过程中把seq_ptr设置为各个不同的数组数列(而非一一写出数列函数的名字) 函数指针数组
const vector *(*seq_int[]) (int) = { 函数指针1,函数指针2,……}
int ADD(int x, int y)
{
return x + y;
}
int SUB(int x, int y)
{
return x - y;
}
int MUL(int x, int y)
{
return x * y;
}
int DIV(int x, int y)
{
return x / y;
}
int main(){
enum calculate_p{
c_add=1,c_sub,c_mul,c_div
};
int(*pfArr[])(int, int) = { 0, ADD,SUB, MUL, DIV };
cout<<pfArr【c_mul】(3,2)<<endl;
}`
//这个时候能正常运行 但是如果是设置成没有参数的函数
比如说 void 函数名() 这样的 运行不了应该有的效果。
然后上面这个pfArr这个 可以使用[]进行直接调用
如果我们想要以指定函数的方式来产生数列 那么我们这时候可以用到枚举类型
记住 枚举类型是可以辅助记忆的常量来进行索引操作
enum 枚举名{ 枚举变量1,枚举变量2,枚举变量3。。。。};
枚举名是一个可有可无的标识符。 大括号里面是用逗号分隔的列表 其中每一个项被称为enumerator 枚举项 默认情况下 第一个枚举项的值是0 接下来每个枚举项都比之前大1。