学习笔记

C++PrimerPlus函数探幽
Publish: 2018/7/23   

内联函数

使用方式:

使用内联函数优点

使用内联函数的缺点

引用变量

当调用函数时,有三种向函数传递参数的方式

  1. 传值调用:该方法把参数的实际值复制给函数的形式参数,修改函数内的形式参数对实际参数没有影响
  2. 指针调用:该方法把参数的地址复制给形式参数,在函数内,该地址用于访问调用中要用到的实际参数。修改形式参数会影响实际参数
  3. 引用调用:该方法把参数的引用复制给形式参数,在函数内,该引用用于访问调用中要用到的实际参数。修改形式参数会影响实际参数
创建引用变量

用&声明引用,必须在声明引用变量时进行初始化

int rat;
int & rodent =rat;
将引用用作函数参数
void swapr(int & a,int & b);
void swapr(int & a,int & b)
{
    int temp;
    temp = a;
    a=b;
    b=temp;
};

什么时候创建临时变量?

将引用参数声明为常量数据的引用

返回引用
const free_throws & clone(free_throws & ft)
{
    free_throws * pt;
    *pt=ft;
    return *pt;
}
free_throws & jolly=clone(three);
何时使用引用参数

默认参数

将值赋给原型中的参数。对于带参数列表的函数,必须从右向左添加默认值。也就是说要为某个参数设置默认值,则必须为它右边的所有参数提供默认值

int harpo(int n,int m=4,int j=6); // VALID
int chico(int n,int m=6,int j); // INVALID

函数重载

函数重载指有多个同名函数,但函数的参数列表也称为函数特征标不同:

何时使用函数重载?

函数模板

使用泛型来定义函数称作模板,在需要多个将同一种算法用于不同类型的函数时,使用模板。

template <typename AnType>
// template <class AnType>
void Swap(AnyType &a,AnType &b)
{
    AnyType temp;
    temp a;
    a=b;
    b=temp;
};
显示具体化

具体化由于常规模板,而非模板函数优于具体化和常规模板

//用于交换job结构的的非模板函数
void Swap(job &,job &);

//函数模板
template<typename T>
void Swap(T &,T &);

//具体化
template <> void Swap<job>(job &,job&);//<job> 是可选的
实例化和具体化

编译器使用模板为特定类型生成函数定义时,得到的是模板实例。

警告:试图在同一个文件(或转换单元)中使用用一种类型的显示实例和现实具体化将出错

编译器如何选择函数版本

策略:

1. 创建候选参数列表
2. 使用候选函数列表创建可行函数列表
3. 确定是否有最佳的可行函数。如果有,则使用它,否则该函数调用出错
    1. 完全匹配,但常规函数优于模板
    2. 提升转换(char和short自动转换为int,float自动转换为double)
    3. 标准转换(int转换char,long转换double)
    4. 用户定义的转换,如类声明中定义的转换

完全匹配允许的无关紧要转换

从实参 到形参
Type Type&
Type& Type
Type[] * Type
Type(argument-list) Type(*)(argument-list)
Type const Type
Type volatile Type
Type* const Type
Type* volatile Type *

最匹配规则

关键字decltype
template<class T1,class T2>
void ft(T1 x,T1 y)
{
    //?type? xpy=x+y;
    decltype(x+y) xpy=x+y;
};

decltype(expression) var为确定类型,编译器必须遍历一个核对表

  1. 如果expression是一个没有用括号括起的标识符,则var的类型与该标识符的类型相同,包括const等限定符
  2. 如果expression是一个函数调用,则var的类型与函数的返回类型相同
long indeed(int)
decltype (indeed(3)) m;//m is type int
// 编译器通过查看函数的原型来获得返回类型,而无需实际调用函数
  1. 如果expression是一个左值,则var为指向其类型的引用,expression是使用括号括起的标识符(expression)
    double xy=4.4;decltype((xy)) r2=xx;//r2 is double &
  2. 如果前面的条件都不满足,则var的类型与expression的类型相同
模板返回值类型
template<class T2,class T2>
?type? gt(T1 x,T2 y)
{
    return x+y;
}
//结合auto h(int x,float y) -> double语法
//-> double 被称为后置返回类型
//auto是一个占位符,表示后置返回类型提供的类型
template<class T2,class T2>
auto gt(T1 x,T2 y) -> decltype(x+y)
{
    return x+y;
}

[左值]:左值参数是可被引用的数据对象,例如,变量、数组元素、结构成员、引用和解除引用的指针都是左值。非左值包括字面常量(用引号括起的字符串除外,它们由其他地址表示)和包含多项的表达式。



← C++PrimerPlus类的使用

Powered by Hexo, Theme designs by @hpcslag.
Style-Framework Tocas-UI designs by @yamioldmel