C++函数相关

程序编译之后的最终产品是可执行程序——由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。

执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,然后跳回到地址被保存的指令处。

内联函数

使用内联函数时,编译器将使用相应的函数代码替换函数调用,如果程序在10个不同的地方调用同一个内联函数,则该程序将包含该函数代码的10个副本。内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。

用法:
在函数声明前加上关键字inline
在函数定义前加上关键字inline

inline是C++新增的特性。C语言使用预处理器语句#define来提供宏——内联代码的原始实现。如:

#define SQUARE(X) ((X)*(X))

但是define语句是通过文本替换来实现的,不能按值传递,如SQUARE(C++)会将C递增两次。而内联函数和常规函数一样,是按值来传递参数的。

注意:
内联函数不能递归

引用变量

引用变量的主要用途是用作函数的形参,通过将引用变量用作参数,函数将使用原始数据,而不是其副本。

C++给&符号赋予了另一个含义,将其用来声明引用。

int rats;
int & rodents = rats;

这样的引用为左值引用,即引用的是一个已经存在的值

引用必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于它。

使用引用的主要原因有两个:
程序员能够修改调用函数中的数据对象。
通过传递引用而不是整个数据对象,可以提高程序的运行速度。(引用参数实际上是基于指针的代码的另一个接口)

默认参数

可以通过函数原型为参数设置默认值:

char * left(const char * str, int n = 1);

这样函数调用left(“theory”, 3)和left(“theory”)都不会出错。

通过使用默认参数,可以减少要定义的析构函数、方法以及方法重载的数量。

函数重载:完成相同的工作,但使用不同的参数列表。

函数模板

函数模板使用泛型来定义函数,其中的泛型可用具体的类型替换。由于模板允许以泛型的方式编写程序,因此有时也被称为通用编程。

template <typename AnyType>
void Swap(AnyType &a, AnyType &b)
{
    AnyType temp;
    temp = a;
    a = b;
    b = temp;
}

关键字template和typename是必需的,除非可以使用关键字class代替typename。

typename使得参数表示类型这一点更为明显,但是有大量代码库是使用class关键字开发的,所以在这种上下文中这两个关键字是等价的。

//非模板函数
void Swap(job &, job &);

//常规模板
template <typename T>
void Swap(T &, T &);

//显式具体化
template <> void Swap<job>(job &, job &);

函数模板本身并不是函数定义,它只是一个用于生成函数定义的方案。编译器使用模板为特定类型生成函数定义时,得到的是模板实例(函数定义)。

隐式实例化:编译器之所以知道需要进行定义,是由于程序调用函数时提供了int参数。

显式实例化:直接命令编译器创建特定的实例:

template void Swap<int>(int, int);

显式具体化:

template <> void Swap<int>(int &, int &);
template <> void Swap(int &, int &);

这些声明的意思是不要使用Swap模板来生成函数定义,而使用专门为int类型显式地定义的函数定义。这些原型必须有自己的函数定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值