函数探幽——内联函数与引用

内联函数用于提高程序执行效率,避免函数调用的开销,但会增加内存使用。宏和内联函数在代码展开上有相似性,但内联函数更安全。右值引用允许对临时对象的操作,优化了参数传递。函数重载依赖于参数列表和类型,而模板则提供了泛型编程的能力,允许编译时的类型推断和函数/类的实例化。
摘要由CSDN通过智能技术生成

内联函数和常规函数的区别在于编译器如何将他们组合到程序中,操作系统将程序指令载入到内存中,因此每条指令都有自己的内存地址,常规函数的调用使得程序跳到另一地址中,在结束后返回,详细过程如下:

执行到函数调用指令时,程序将在函数调用后,首先保存当前堆栈地址,跳到函数起点的内存单元开始执行函数代码,将函数返回值放入寄存器中,执行后跳回执行前的堆栈地址,这种来回跳跃将有一定的开销;

C++内联函数将使得编译器使用相应的函数代码替换函数调用,这样程序在执行时就不必来回跳跃,内联函数比常规函数的运行速度更快;但代价就是占用更多的内存,因为相当于没有写这个函数而是在代码里展开了。

使用内联函数的方式:

在函数的声明和定义前加上inline关键字;通常的做法是省略原型,在整个定义放在本应提供原型的地方,但类似于reigster,编译器不一定会将函数看作内联函数,尤其要注意的是内联函数不能递归的调用;

内联函数的原始实现是宏,但宏是文本替换,这将出现一些问题;比较稳妥地考虑是使用内联函数替换宏;


#define SQUARE(x)  x*x;
inline double square(double x){return x*x;}
int c=0;
square(c++)->c*c,c++;
如果用宏:c++*c++;使得c递增两次;

可以对宏做出改进:
#define SQUARE(X) ((X)*(X))

引用变量:右值引用与左值引用

有时C++需要对右值进行引用,如果不采用右值引用符&&,则需要左值const引用,然后编译器会创建临时变量,形参指向该变量,但不能修改它;将以往的引用成为左值引用;引用主要用于结构,类等自定义数据类型,而不是基本的内置类型,

引用变量方便函数在处理大型数据时不必浪费空间;引用接近于const指针,必须在创建时初始化,与变量关联后无法改变;

在函数的参数传递过程中,引用参数必须接收实际变量(在内存中有确定的地址);如果不是,那么如果引用参数为const,C++将编译器将允许创建临时变量,当然实参也要满足如下要求:

实参的类型正确,但不是左值(允许发生赋值操作,但const也是左值,现在一般指可被引用的数据对象,我们还是用是否允许赋值来区分左右值);常规变量是可修改的左值,const变量是不可修改的变量;

实参的类型不正确,但可以转换为正确的类型(隐式转换);

非左值包括:字面常量,多项表达式;

注意:创建的临时变量只在函数调用期间存在,此后编译器可以将其删除;创建临时变量只在函数参数列表里是常量引用时才可以发生;

double refcube(const double&rre){return ra*ra*ra;}
double x=3.0;
refcube(x+3);这是允许的,但如果refcube的参数是double&时则将报错;

C++新增了右值引用&&:这种引用可以指向右值

double &&rref=std::sqrt(36.00);
cout<<rref;

函数重载的关键:函数参数列表——函数特征标

若两个函数的参数数目和类型,排列顺序相同,那么函数的特征标相同;关键函数匹配即在于调用时的优先顺序,这因为类型转换,默认参数,引用,常量,顶层底层const的出现而变得复杂;

引用与类型本身:编译器在检查特征标时,将类型引用与类型本身视为同一个特征标;

const:将非const赋给const是合法的,反之则是非法的;

函数匹配:函数将调用最匹配的版本;这里具有层次;

void staff(double&r1);
void staff(const double&r1);

void staff(double &&r1);


double x=1.0;
const double y=3.0;


staff(x);  //void staff(double&r1);
staff(x+y);  //void staff(double &&r1);如果没有该函数将调用void staff(const double&r1);
//
staff(y);    //void staff(const double&r1);

重载模板

匹配顺序:非模板函数>具体化模板>

template<class T>

void swap(T&,T&);

具体化格式:

template<>void swap<job>(job&a,job&b);


实例化格式:
template void swap<int>(int&,int&);

swap<int>(a1,a2);

只使用template是实例化,使用template <>是具体化;

常规模板;

实例化和具体化:

完全匹配与最佳匹配

编译器会根据实参和形参之间的转换来选择函数,这里有顺序:

1.完全匹配;

2.提升转换;

3.标准转换;

4.用户定义的转换(基类与派生类指针,引用的转换);

完全匹配如下表:

注:const的区别只适用于指针和引用,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值