您的位置:首页 > 编程语言 > C语言/C++

重新学习《C++Primer5》第6章-函数

2016-04-13 16:58 477 查看

6.1 函数继承

1.局部静态对象

size_t count()
{
static size_t ctr=0;
return ++ctr;
}
int main()
{
for(size_t i=0;i<10;++i)
cout<<count()<<endl
return 0;
}//输出1到10的数字


局部静态对象第一次经过初始化,如果没有被显示初始化,则将执行值初始化(内置类型初始化为0),直到程序终止才被销毁。

6.2 参数传递

1.传值参数

指针形参可以改变所指对象的值,但在C++中建议使用引用类型的形参替换指针。

2.引用参数

使用引用避免拷贝

使用引用形参返回额外的信息

可以处理需要返回多个值得情况

3.const形参和实参

实参初始化形参是会忽略到顶层const

void fun(const int i){}//可以传递const和非const类型,但不能改变i值。
void fun(int i);//错误:重复定义


可以用非const初始化const对象,但反过来不行

int i=12;
const int *cp=&i;//正确,但cp不能改变i
const int &r=i;//正确,但r不能改变i
const int &r2=22;
int *p=cp;//错误:类型不匹配
int &r3=r;//错误:...
int &r3=22;//错误:...


尽量使用常量引用

4.数组形参

不允许拷贝数组,使用数组时自动转换成指针

使用beg和end传递数组参数

数组引用参数

void print(int (&arr)[10])
{
for(auto ele:arr)
cout<<ele<<endl;
}
int i=0,j[2]={1,2};
int k[10]={...};
print(&i);//错误:实参不是含有10个整数的数组
print(j);//error
print(k);//正确


传递多维数组

void print(int (*matrix)[10],int size);//等价于
void print(int matrix[][10],int size);


5.main:处理命令行选项

6.含有可变形参的函数

initializer_list形参

是一个模板类型,但对象中的元素永远是常亮值

void error_msg(ErrCode e,initializer_list<string> il)
{
cout<<e.msg()<<":";
for(const auto &elem:il)
cout<<elem<<" ";
cout<<endl;
}
error_msg(ErrCode(42),{"functionx",expected,actual});
error_msg(ErrCode(42),{"functionx","okay"});


6.3 返回类型与return

1.返回值:不要返回局部对象的引用或指针

2.返回数组的指针或引用

使用类型别名返回数组指针

typedef int arrT[10];
using arrT=int[10];
arrT* func(int i);//返回一个指向含有10个整数的数组的指针


直接声明

int arr[10];
int *ap1[10];//含有10个指针的数组
int (*ap2)[10]=&arr;//指向10个整数的数组
//返回数组指针的函数形式如下:
Type (*function(parameter_list))[dimension];
int (*func(int i))[10];


3.使用尾置类型返回

使用尾置

auto func(int i)->int(*)[10];


使用decltype

int odd[]={1,2,3,4,5};
decltype(odd) *arrPtr(int i)
{
return ...
}


6.4 函数重载

重载和const形参

拥有顶层const的形参和没有const的形参无法区别

void func(int);
void func(const int);//error


如果形参是引用或者指针,则可以用const实现重载

void func(int*);
void func(const int*);//OK


2.const_cast和重载

const string &shorterString(const string &s1,const string &s2)
{
return s1.size()<=s2.size()?s1:s2;
}
string &shorterString(string &s1,string &s2)
{
auto &r=shorterString(const_cast<const string&>(s1),const_cast<const string&>(s2));
return const_cast<string&>(r);
}


6.5 特殊用途语言特性

默认参数

一旦有某个形参被赋予了默认值,后面的必须有默认值

调用时按先后顺序

内联函数和constexpr函数

内联机制用于规模小、流程直接、频繁调用的函数

constexpr用于常量表达式的函数

constexpr int new_sz(){return 42;}
constexpr int foo()=new_sz();


把内联函数和constexpr放在头文件中

3.assert预处理宏

assert(expr);//如果expr为真,则不做处理,如果为假,则输出信息并终止程序执行


4.NDEBUG预处理变量

可以使用NDEBUG编写自己的条件调试代码,如果NDEBUG未定义,将执行#ifndef和#endif之间的代码;如果定义了DNEBUG,这些代码将被忽略

void print(const int ia[],size_t size)
{
#ifndef NDEBUG
...
#endif
}


6.6 函数匹配

首先寻找候选函数(函数名),在寻找可行函数(参数)

6.7 函数指针

bool lengthCompare(const string&,const string&);
bool (*pf)(const string&,const string&);
pf=lengthCompare;//pf为函数指针,执行函数


1.函数指针形参

形参是函数则自动转换为函数指针

void useBigger(const string&,const string&,
bool pf(const string&,const string&));
//等价于
void useBigger(const string&,const string&,
bool (*pf)(const string&,const string&));


2.返回指向函数的指针

虽然不能返回一个函数,但可以返回指向函数的指针

//使用别名
using F=int(int*,int);
using PF=int(*)(int*,int);
PF f1(int);
F f1(int);//错误,不能返回函数
F *f1(int);
int (*f1(int))(int*,int);//直接声明


3.将auto和decltype用于函数执行类型

size_type sumLength(const string&,const string&);
decltype(sumLength) *getFcn(cons string&);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: