C++学习笔记9:函数 part 2

补充C++基础笔记。

函数 part 2:函数重载、特殊用途语言特性、函数匹配、函数指针

函数重载

定义:如果同一作用域内的几个函数名字相同但形参列表不同,我们称之为重载函数 -> 编译器会根据传递的实参类型推断想要的是哪个函数

  1. 几对无法区分的重载函数
    (1) 除返回类型外其他所有要素都相同的两个函数;
    (2) 形参仅仅是名字不同;
    (3) 拥有顶层const的形参 v.s 没有顶层const的形参;
    如:
Record lookup(Phone);
Record lookup(const Phone);  //重复声明了Record lookup(Phone)

Record lookup(*Phone);
Record lookup(Phone* const);  //重复声明了Record lookup(Phone*)

但是能区分底层的:

Record lookup(Account&);  //函数作用于Account的引用
Record lookup(const Account&);   //新函数,作用于常量引用

Record lookup(Account*);  //新函数,作用于指向Account的指针
Record lookup(const Account*);  //新函数,作用于指向常量的指针 
  1. const_cast和重载:调用返回值是const的函数时,使用const_cast去掉const
//比较两个string对象的长度,返回较短的那个引用
const string &shortString(const string &s1, const string &s2)
{
	return s1.size() <= s2.size() ? s1 : s2;
}

//非常量返回值的调用
const string &shortString(const string &s1, const string &s2)
{
	auto &r =  shortString(const_cast<const string&>(s1), const_cast<const string&>(s2));
	return const_cast<string&>(r);
}

特殊用途语言特性

默认实参
  1. 给定的作用域中一个形参只能被赋予一次默认实参。
// 表示高度和宽度的形参没有默认值
string screen(sz, sz, char = ' ');
string screen(sz, sz, char = '*');  //错误:重复声明
string screen(sz = 24, sz = 80, char);  //正确,添加默认实参
  1. 局部变量不能作为默认实参。
内联函数和constexpr函数:通常定义在头文件内
  1. 将函数指定为内联函数,可以将类似cout << shorterString(s1, s2) << endl在编译过程中展开为类似cout << (s1.size() < s2.size() ? s1 : s2) << emdl的形式,从而消除shorterString函数的运行开销。
    内联机制用于优化规模较小、流程直接、频繁调用的函数 – 内联说明可以选择忽略这个请求。
  2. constexpr函数:指能用于常量表达式的函数。
    约定:函数的返回值及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。
constexpr int new_sz() { return 42; }
constexpr int foo = new_sz();  //正确:foo是一个常量表达式

constexpr被隐式地指定为内联函数。
constexpr函数体内也可以包含其他语句,只要这些语句在运行时不执行任何操作就行。

//如果arg是常量表达式,则scale(arg)也是常量表达式
constexpr size_t scale(size_t cnt)  { return new_sz() * cnt; }

int arr[scale(2)];  //正确:scale(2)是常量表达式
int i = 2;  //i不是常量表达式
int a2[scale(i)];  //错误:scale(i)不是常量表达式
调试帮助:assert和NDEBUG
  1. assert预处理宏:定义在cassert头文件中
    assert(expr)对expr求值,如果表达式为假,assert输出信息并终止程序地执行,否则assert什么也不做。
  2. NDEBUG预处理变量:定义了NDEBUG,则assert什么也不做。

函数匹配

步骤一:确定候选函数和可行函数:
候选函数:与被调用的函数同名+声明在调用点可见
可行函数:形参数量与本次调用提供的实参数量相等+每个实参的类型与对应的形参类型相同
步骤二: 寻找最佳匹配(如果有的话)

函数指针

函数指针指向的是函数而非对象。
bool lengthCompare(const string &, const string &);
bool (*pf) (const string &, const string &); //未初始化

使用函数指针

把函数作为一个值使用时,该函数自动转换成指针:

pf = lengthCompare;   //pf指向名为lengthCompare的函数
pf = &lengthCompare;  //等价的赋值语句:取地址符可选
参考资料:
  1. C++ primer. 第五版.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值