内联函数+引用+模板

inline-内联函数的使用

使用方式

  1. 在函数声明前加上inline
  2. 在函数定义前加上inline
inline double square(double x){return x*x;}//函数定义前
#include<iostream>
using namespace std;
inline double square(double x);
int main()
{
    cout<<square(16)<<endl;
    return 0;
}
double square(double x){return x*x;}//函数声明前

内联与宏

宏事实上是一种文本替换的方式,比如

#define square(X) X*X
#include<iostream>
using namespace std;
int main()
{
    int c=5;
    cout<<square(4.5)<<'\t'<<"4.5*4.5"<<endl;
    cout<<square(4.5+7.5)<<'\t'<<"4.5+7.5*4.5+7.5"<<endl;
    cout<<square(c++)<<'\t'<<"c++*c++"<<endl;
    return 0;
}
//结果是20.25 45.75 30

可以看到其实就是用数字或者表达式代替了X的位置,需要指出尽量避免这样使用,使用内联函数会更好

引用变量

1.创建引用变量

int& rodents=rats;

注意:

  1. 可以确认的是这两个变量指向相同的地址
  2. &在这里并不是取址运算符
  3. 引用变量必须在声明时就进行初始化不能出现int & rodents;
  4. 引用变量一旦与某个变量关联起来就一直效忠于它
//如下代码无法改变rodent引用的还是rats这一事实
int rats=101;
int *pt=&rats;
int &rodents=*pt;
int bunny=50;
pt=&bunny;

2.使用引用(左值)作为函数参数

2.1.简单使用

//考虑一下两个交换函数
void swap(int &a,int &b);
void swap(int a, int b);

很简单,前者能交换原函数的两个参数,而后者不行

2.2.需注意事项

引用变量传递参数只能是传递变量,无法传递表达式以及常量

swap(a+3,b+6);

2.3.应尽可能使用const

可优化方案:引入关键字const可以产生临时变量储存传入的值从而不会出现无法执行的情况,同时如果引用对象的值发生改变,系统无法编译

#include<iostream>
using namespace std;
double cube(const &ra){return ra*ra*ra;}
int main()
{
    double side=3.;
    double *pd=&side;
    double & rd=side;
    long edge=5L;
    double lens[4]={2.0,3.0,5.0,6.0};
    double c1= cube(side);
    double c2= cube(lens[2]);
    double c3= cube(rd);
    double c4= cube(*pd);
    double c5= cube(edge);
    double c6= cube(7.0);
    double c7= cube(side+10.0);
    return 0; 
}

以上都是可以执行的,尽管是edge以及7.0和side+10.0系统将创建一个临时变量储存他们,并进行引用

2.4.右值引用

double && rref=std::sqrt(36.00);//正确
double & rref=sqrt(36.00);//错误

2.5.将引用用于结构

2.5.1 返回引用

​ 当返回值为引用的时候,效率更高,因为普通的return事实上创建了一个中间变量,进行了两次复制才完成相同的操作

#include<iostream>
using namespace std;
#include<string>
   struct people{string name;int age;int sex;double money;};
void add_money(people & one)
{
    cout<<"great congratulations to you!"<<endl;
    one.money+=10000;
}
void show_state(const people & one)
{
    cout<<"now,you:"<<endl;
    cout<<one.name<<endl;
    cout<<one.age<<endl;
    cout<<one.sex<<endl;
    cout<<one.money<<endl;
}
people & trade(people & one)//返回一个结构的引用
{
    one.age+=10;
    one.money*=2;
    return one;
}  
int main()
{
    people one={"xiaoming",18,0,0.1};
    cout<<"the first condition:"<<endl;
    show_state(one);
    add_money(one);
    show_state(one);
    cout<<"a devil trade with you"<<endl;
    show_state(trade(one));//show_state的传入参数是one的引用所以one展示的是one的引用的引用,还是与one一个地址
    return 0;
}

注意:

  1. 返回函数时避免返回临时创建的变量引用,因为这种变量往往在函数结束调用就被系统清除内存
//比如下面这段代码
const people & cloze(people & one)
{
    people two;
    two=one;
    return two;//Big error.two马上就会被清除内存,于是其引用即将无效
}

函数模板

简要介绍

函数模板可以函数有同时对不同的数据类型进行操作,使用该方法,你可以给函数的参数列表放入各种类型的实参

#include<iostream>
using namespace std;
template <typename Anytype>//"只能"创建一次,Anytype只是一个可以任意取名的名字
void Swap(Anytype &a,Anytype &b)
{
    Anytype temp;
    temp=a;
    a=b;
    b=temp;

}
//但是在作用完后可以再创建一次template <typename Anytype>,比如这里
int main()
{
    double x=100;double y=10.323242;
    Swap(x,y);//替换两个浮点数的值
    cout<<x<<'\t'<<y<<endl;
    int a=23,b=19;
    Swap(a,b);//替换两个整数
    cout<<a<<'\t'<<b;
    return 0;
}
注意
  1. typename可以是class,而且都不要加分号
template <typename T> /*is the same as*/
template <class T>
    
  1. 该方法只是使函数定义更简单,并没有使复杂度降低。

  2. 模板虽然具有通用性,但是并不是所有的类型都会满足某一特定的运算符

//比如赋值运算符
template <class T>
void f(T a,T b)
{
    a=b//may be an error.比如T是数组类型,因为数组没有赋值这一说法
}
  1. 如果现在已经有了一个非模板函数与一个同名同类型的模板函数,优先调用非模板函数
#include <iostream>
using namespace std;
template <class T>
T fun(T a,T b)
{
    return a+b;
}
int fun(int a,int b)
{
    return a+2*b;
}
int main()
{
    int m=78,n=89;
    cout<<fun(m,n)<<endl;
    return 0;
}
//编译后结果输出256,可以看出优先采用了第二种定义方式
拓展
  1. 混合使用任意定义参数
#include <iostream>
using namespace std;
template <class T,class A>//一个实例
void add(T a,A b)
{
    decltype(a) res=a+b;//你可以这样理解,把a的类型赋给res,甚至可以人为这是一种初始化的操作
    cout<<res<<endl;
}
int main()
{
    int LIM=520;
    double MIL=1314000.0;
    add(LIM,MIL);
    return 0;
}
  1. decltype的拓展

但是一旦考虑return这样一个函数,我们并不知道应该返回何种类型

?type? add(T a,A b)
{
    return a+b;
}

解决方案:

通式:auto function (typename para1,...) ->type(可以是double,也可以是decltype(parament))

#include <iostream>
using namespace std;
template <class T,class A>
auto add(T a,A b) ->decltype(a)//使输出结果为a的类型
{
    return a+b;
}
int main()
{
    int LIM=520;
    double MIL=1314000.0;
    cout<<add(LIM,MIL);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值