一、内联函数

    常规函数和内联函数的区别在于C++编译器如何将他们组合到程序中。编译过程的最终产品是可执行程序--由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,然后跳回到地址被保存的指令处。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。

    有了内联函数,编译器使用相应的函数代码替换函数调用。对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。内联函数的运行速度比常规函数快,但是代缴是需要占用更多的内存。

    使用这项特性,必须采取下述措施之一:

  • 在函数声明前加上关键字inline;
  • 在函数定义前加上关键字inline;

二、引用变量

    引用是已定义的变量的别名。主要作用是用作函数的参数。通过将引用作参数,函数将使用原始数据,而不是副本。因此,除了指针之外,引用也为函数处理大型结构提供了一种非常方便的途径。

  1)创建引用变量

    int rats;

    int & temp=rats;

    &不是地址运算符,而是类型标示符的一部分。就像声明中的char* 指的是指向char的指针一样,int &指的是指向int的引用。

    int rats=10;

    int & temp=rats;

    int * temp1=&rats;

    不过引用必须在声明引用变量时进行初始化。引用更接近const指针,必须在创建时进行初始化,一旦与某个变量关联起来,就效忠于它。

    int & temp=rats;

    实际是下述代码的伪装表示:

    int * const pr=&rats;

    对于上述的引用变量temp,如果一个变量再为int wang=10;

    temp=wang;

    最终的结果是:temp还是指向rats,只不过这个时候rats的值为10,地址仍旧为rats,并不是和wang的地址一样。

    再看下下面的代码:

int rats=101;
int * pt=&rats;
int & temp=*pt;
int bun=10;
pt=&bun;

将temp初始化为*pt使得temp指向rats,接下来将pt的指向改为bun,通过这种方式企图修改引用temp的值,是不可能的。
  2)将引用用作函数参数

    引用经常被用作函数参数,使得函数中的变量名称为调用程序中的变量的别名。这种传递参数的方法称为引用传递。按引用传递允许调用的函数能够访问函数中的变量。C语言只能按值传递,按值传递导致被调用函数使用调用程序的值的拷贝。还是看段代码自己领悟吧:

#include <iostream>
using namespace std;
double cube(double a)
{
a*=a*a;
return a;
}
double refcube(double & a)
{ a*=a*a;
return a;
}
int main()
{
double a=3;
cout<<cube(a);
cout<<"= cube of"<<a<<endl;
cout<<refcube(a);
cout<<"= refcube of "<<a<<endl;
return 0;
}

对于合适使用引用参数,可以根据自己思考的结果,使用引用参数的主要原因有两个:

  • 程序员能够修改调用函数中的数据对象。
  • 通过传递引用而不是整个数据对象,可以提高程序的运行速度。

三、函数重载

    函数多态(函数重载)能够使用多个同名的函数。其中函数多态和函数重载这两个术语是同一个概念。重载函数就像是有多个含义的动词。使用上下文确定要使用的重载函数版本。

    如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则他们的特征相同,而变量名是无关紧要的。C++允许定义名称相同的函数,条件是他们的特征标志不同。

四、函数模板

    函数模板允许以任意类型的方式来定义函数:

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

    第一行指出,要建立一个模板,并将类型命名为Anytype。关键字template和typename是必需的,除非可以使用关键字class代替typename。必须使用尖括号。类型名可以任意选择(这里为Anytype)。但是需要注意的就是,在自己写练习时,模板函数名不能使用swap,因为模板中也有这么一个模板。对于模板,也是可以重载的,重载的过程和原来一样。在模板显示实例化,可以通过一个例子来说明:

template <typename T>
T add(T a,T b)
{
return a+b;
}
.....
int m=6;
double x=10.2
cout<<Add<double>(x,m)<<endl;

上述例子就是显示实例化的例子。

  1)编译器选择使用哪个函数版本、

    对于函数重载、函数模板和函数模板重载,C++需要一个定义良好的策略,来决定为函数调用使用哪一个函数定义,尤其是有多个参数时。这个过程称为重载解析,大体步骤:

  • 创建候选函数列表。包括与被调用函数的名称相同的函数和模板函数
  • 使用候选函数列表创建可行函数列表。
  • 确定是否有最佳的可行函数。


C++ primer(八)--内联函数 引用变量 引用传递函数参数 函数重载/模板/模板具体化的更多相关文章

  1. php引用(&)变量引用,函数引用,对象引用和参数引用用法

    php引用(&)变量引用,函数引用,对象引用和参数引用用法   php的引用(就是在变量或者函数.对象等前面加上&符号) 在PHP 中引用的意思是:不同的名字访问同一个变量内容.与C语 ...

  2. js匿名函数(变量加括号就是函数)

    js匿名函数(变量加括号就是函数) 一.总结 变量加括号就是函数,而函数的括号是用来传参的 1.类比:以正常函数去想匿名函数,匿名函数比正常函数只是少了函数名,本质还是一样,该怎么传参还是怎么传参,小 ...

  3. 使用内联的 CSS 变量技巧,提高灵巧布局效率!

    作者:Ahmad shaded 译者:前端小智 来源:sitepoint 点赞再看,微信搜索**[大迁世界]**关注这个没有大厂背景,但有着一股向上积极心态人.本文 GitHub github.com ...

  4. C++ 指针 引用 变量引用

    变量引用: 引用的作用就是给变量起个别名,假如有一个变量a,想给它起个别名b,         可以这么写:int a;//定义a是整型变量.int &b=a;//声明b是a的引用. 上面就是 ...

  5. C++初阶(命名空间+缺省参数+const总结+引用总结+内联函数+auto关键字)

    命名空间 概述 在C/C++中,变量.函数和后面要学到的类都是大量存在的,这些变量.函数和类的名称将都存在于全局作用域中,可能会导致很多冲突.使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲 ...

  6. 嵌入式C语言自我修养 10:内联函数探究

    10.1 属性声明:noinline & always_inline 这一节,接着讲 __atttribute__ 属性声明,__atttribute__ 可以说是 GNU C 最大的特色.我 ...

  7. C++内联函数与宏定义

    用内联取代宏: 1.内联可调试: 2.可进行类型安全检查或自动类型转换: 3.可访问成员变量. 另外,定义在类声明中的成员函数自动转化为内联函数. 文章(一) 内联函数与宏定义 在C中,常用预处理语句 ...

  8. (转)内联(inline)函数与虚函数(virtual)的讨论

    本文转自: http://topic.csdn.net/t/20051220/09/4469273.html 函数的inline属性是在编译时确定的, 然而,virtual的性质是在运行时确定的,这两 ...

  9. c++ 内联函数 (讲解的TM真好)

    1.  内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码如下: int max(int a, int b) {  return a > b ? a : b; } 为 ...

随机推荐

  1. 两个由于php.ini配置错误导致的报错:ajax图片上传报错和exec报错

    遇到了两个由于php.ini配置错误导致的报错:ajax图片上传报错和exec报错 首先第一个: 在做一个用ajax图片上传的功能中,php报了这样一个错误:File upload error - u ...

  2. [swift] NSClassFromString 无法获得该类

    在写OC的时候需要用 NSClassFromString(classStringName)获得一个类,如果存在就用这个类型来声明一个对象, 但是在swift的时候却往往得不到这个类,为什么呢? 从截图 ...

  3. WebApi学习总结系列第二篇(webapi的调试)

    目前使用webapi的调试主要有 1.用接口宿主调试.(宿主形式多样:web.winform.还有就是直接用app进行接口调试) 2.用Fiddler抓Http信息,进行调试. 1.用接口宿主调试. ...

  4. codeforces 278Div1 B题

    虚拟参赛的时候没想到是线段树,看到很多人都过了,也蛮着急的. 首先用二分+线段树的方法更新DP[i]:它表示以A[i]为结尾可以最前到哪个位置: 再用线段树计算ans[i]:它表示当前i个A元素可以最 ...

  5. 为你的TabBar添加Badge-感谢分享

    实现过程 首先定义了三种Badge类型 typedef NS_ENUM(NSUInteger, CustomBadgeType){ kCustomBadgeStyleRedDot, //显示普通红点类 ...

  6. *[hackerrank]Tree Covering

    https://www.hackerrank.com/contests/illuminati/challenges/tree-covering 这道题先是在上次交流讨论了一下,然后两位百度的朋友先写完 ...

  7. SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-003-@Conditional根据条件生成bean及处理profile

    一.用@Conditional根据条件决定是否要注入bean 1. package com.habuma.restfun; public class MagicBean { } 2. package ...

  8. 程序异常捕获库 - CrashRpt

    CrashRpt.dll用来在应用程序出现异常crash时,捕获到错误. 并收集出错信息: MiniDump文件.硬件信息.系统信息.出错信息.进程信息.服务信息.驱动信息.启动信息.软件列表.端口信 ...

  9. QWidget与HWND的互相转换

    QWidget与HWND的互相转换 在编写Windows的应用程序时,我们有时不可避免地要与Windows平台固有的Win32 API打交道,但是Win32 API里面常常用到的HWND等诸多句柄QT ...

  10. 2-3 tree使用

    The 2-3 tree is also a search tree like the binary search tree, but this tree tries to solve the pro ...