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

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 函数重载

  1. 重载和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 特殊用途语言特性

  1. 默认参数
    一旦有某个形参被赋予了默认值,后面的必须有默认值
    调用时按先后顺序
  2. 内联函数和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&);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值