CppPrimer笔记 Chapter6 函数

时间:2021-03-09 17:35:38

CppPrimer笔记 Chapter6 函数

标签: Cpp


含有可变形参的函数基础(6.2.6)

  • 实参类型相同,使用initializer_list
#include <iostream>

using namespace std;

int sum(initializer_list<int> il)
{
int sum = 0;
for (auto it = il.begin(); it != il.end();++it)
{
sum += (*it);
}
return sum;
}
int main()
{
cout << sum({3, 2, 3, 1}) << endl;
system("pause");
}
  • 省略符形参
//计算number个int数的和
int sum(const int number, ...)
{
//函数参数是以数据结构:栈的形式存取,从右至左入栈。

va_list arg_ptr;//va_list 是一个字符指针,可以理解为指向当前参数的一个指针
int sum = 0;
va_start(arg_ptr, number);//对arg_ptr进行初始化,让它指向可变参数表里面的第一个参数
for (int i = 0; i < number; ++i)
{
sum += va_arg(arg_ptr, int);
}
va_end(arg_ptr);//将arg_ptr指针关掉,以免发生危险
return sum;
}
int main()
{
cout << sum(3, 2, 3, 1) << endl;
system("pause");
}

函数重载(6.4)

  • main函数不能重载
  • 重载函数必须有形参上的不同,形参相同而返回类型不同则第二个函数的声明为错误.同时,别名与原名视为相同
typedef int same_int;
void fun(int);
int fun(int);//error
int fun(same_int);//error
  • 顶层const不影响传入函数对象,可认为忽略.
int fun(int);
int fun(const int);//error
  • 函数匹配
  • 被内嵌作用域隐藏了的外层的同名函数,直接视为不可见.不会进行搜索与重载

默认实参(6.5.1)

  • 给定作用域中的一个形参只能被赋予一次默认实参,即使多次赋予的某一个参数的默认实参是相同的值
  • 用作默认实参的名字在函数声明所在的作用域内解析,而名字的求值过程发生在函数调用时. 即: 默认实参不会被同名局部变量覆盖,同时若在调用函数之前修改了默认实参对应的变量,则调用时会传入新的值
int x = 10;
int y = 20;
void print(int a = x, int b = 20)
{
cout << a << endl;
cout << b << endl;
}
int main()
{
x = 50;
int y = 100;
print();//输出 50 20
system("pause");
}

函数匹配(6.6)问题

  • 步骤
    1. 寻找候选函数,然后寻找可行函数–即寻找可以调用的函数
    2. 寻找最佳匹配
    3. 含有多个形参都匹配的函数
      • 该函数每个实参的匹配都不劣于其它可行函数需要的匹配
      • 至少有一个实参的匹配优于其它可行函数提供的匹配
        否则,存在二义性,报错.
void f(){ cout << "f_void"; }
void f(int x){ cout << "f_int"; }
void f(int x, int y){ cout << "f_int_int"; }
void f(double x, double y = 3.14) { cout << "f_double_double"; }

int main()
{
f(5.6);
f(42, 2.56);//error
system("pause");
}
  • 最佳匹配
    优先级从高到低
    1. 精确匹配:
      • 实参类型与形参相同
      • 实参从数组类型或函数类型转化为相应指针函数指针
      • 向实参添加顶层const或从实参删除顶层const
    2. 通过const转化实现的匹配待链接
    3. 通过类型提升实现匹配待链接
    4. 通过算术类型转换待链接或指针转换待链接实现的匹配
    5. 通过类类型转换实现的匹配待链接
void ff(int);
void ff(short);
ff('a'); //char提升成int;调用f(int)

void manip(long);
void manip(float);
manip(3.14); //二义性调用 都为算术类型转换

int lookup(int&);
int lookup(const int&);
const int a ;
int b;
lookup(a); //调用lookup(const int&)
lookup(b);//调用lookup(int&);

函数指针(6.7)

  • 声明定义并使用函数指针
bool lengthCompare(const string & s1, const string &s2)
{
return (s1.length() > s2.length());
}

int main()
{
bool(*pf)(const string&, const string&);
pf = lengthCompare;
cout << &lengthCompare << endl;
cout << pf << endl;

cout << pf("long", "srt") << endl;
system("pause");
}
  • 函数指针形参
  • 不带括号的函数名可以当成常量函数指针使用,但是不是等价,还不清楚
bool lengthCompare(const string & s1, const string &s2)
{
return (s1.length() > s2.length());
}

void useBigger(const string &s1, const string &s2,
bool pf(const string &, const string &))
{
if (pf(s1,s2) == true)
{
cout << "s1 > s2" << endl;
}
else
{
cout << "s1 <= s2" << endl;
}
}

int main()
{
useBigger("longer", "short", lengthCompare);

system("pause");
}
  • 返回指向函数的指针
using F = int(int*, int);
using PF = int(*)(int*, int);

PF f1(int);
F *f2(int);
auto f3(int) -> int(*)(int*, int);