1. 内联函数

  1. 普通函数调用:

    存储调用指令的地址-》将函数参数复制到堆栈-》跳到函数地址执行代码(返回值放到寄存器)-》跳回调用指令处

  2.  当代码执行时间很短,且会被大量调用的时候,使用内联函数将节省调用的时间。

  3.  定义方法:

    省略原型,并将整个定义放在本应该放原型的地方,书写的时候尽量将整个函数放到一行中,如果函数占多行就不太合适作为内联函数。

inline double square( double x) { return x * x; }

  4.  内联函数不能递归调用。

2.引用变量

  1. 引用变量的主要用作是用途函数的形参。通过将引用变量用作参数,函数将使用原始数据,而不是其拷贝。(就是一个有多个名称的同一个变量)。
  2. 引用是专门为结构和类设计的,不能用作数组。
  3. 创建引用变量:
      
    int x = ;
    int & refx = x;

    int & 指的是指向int的引用。
    注:引用必须在声明的时候进行初始化。而不能后来通过赋值来设置
    特别接近于const指针:

    int & rodent = rat;
    //特别接近于下面的代码:
    int * const pr = rats;
  4. 引用传递:
    将引用用作函数参数进行 参数传递的方法
  5. 常量引用:
    引用变量的原值而不对变量做任何修改时,用const。(此种情况下,如果数据比较小时尽量采用值传递,当数据比较大时,采用引用参数将很有用)。
  6. 左值参数:
    可以被引用的数据对象,如变量、数组元素、结构变量、引用和被解除引用的指针等。
    非左值包括字面值常量、包含多项的表达式等。
  7. 如果函数调用的参数 不是左值 或 与相应的const引用的参数不匹配,则C++将创建类型正确匿名变量,将函数调用的参数的值传递给该匿名变量,并让参数来引用该变量。
  8. 允许的条件下尽可能使用const值,可以接受const和非const类型的实参,否则只接受非const实参。
  9. 对于返回值为引用类型的函数,实际上是被引用的变量的别名。
  10. 返回引用的函数不应返回临时变量的引用。如果指向临时变量的引用,函数运行完毕后,它将不复存在,引用就指向了不存在的内在单元中:
    const myStruct & clone(myStruct & stru)
    {
    myStruct tmp = stru;
    return tmp;//错误
    }

    将返回值定义为const myStruct &类型表明不能使用该返回值来修改引用指向的结构。

  11. 引用的形参类型和实参类型不匹配但可以自动转换时,会生成一个临时变量,然后将该临时变量的引用传递给形参。
  12. 基类引用可以指向派生类对象,而无需强制类型转换。
  13. iostream和派生类fstream对象的几个方法:
    ofstream os;
    ios_base::fmtflags initial = os.setf(ios::fixed);//定点表示模式,返回值为fmtflags类型,表示之前的所有格式,以便结束后还原设置
    os.precision();//定点模式下显示多少位小数
    os.setf(ios::showpoint);//显示小数点的模式
    os.width();//输出的下一个值要占几个字段宽度
  14. 引用与指针的使用场合:
    * 数据对象是数组时,必须使用指针。
    * 如果是结构,则使用 引用 或 指针。
    * 数组对象是小型C++内置的数据类型时,要修改值就用指针,不要修改值的直接按值传递。
    * 如果数据对象是类,则使用引用,这也是引用被增加的原因。

3.默认参数

  1. 必须通过函数原型来来设置默认值.

    int harpo(int n ,int m = , int j = );
  2. 而且设置默认值时,必须从右到左依次设置,如果一个参数设置了默认值,那么它的右侧所有的都要设置默认值。
  3. 调用时,不能跳过任何参数,即使使用默认值:
    harpo(, ,);//
    harpo(,);//省略也是从右到左,中间的不能跳过

4.函数重载

  1. 函数是否可以重载是根据特征标来判断。

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

    特征标是根据函数的 参数(参数类型和排列顺序)来确定的
    并且编译器检查时把 引用类型和类型本身视为同一个特征标,匹配函数时,也不会区分const和非const。

  2. 名称修饰:
    C++编译器对函数名称进行的加密,具体是根据函数的特征标对每个函数名进行修饰。

5.函数模板

  1. 模板声明:

    template <typename XJP>//考虑向后兼容时,也可以用class XJP。尽量使用typename
    void method (XJP &a, XJP &b)
    {
    XJP tmp;
    tmp = a;
    a = b;
    b = tmp;
    }
  2. 显式具体化模板函数:声明和定义都以template <>开头,并显式指定类型:
    template <> void Swap<job> (job &, job &);

    其中Swap<job>中的<job>是可选的,因为参数列表已经表明类型,所以可以写成这样:

    template <> void Swap (job &, job &);
  3. 对于给定的函数名,可以有非模板函数、模板函数 和 显式具体化模板函数 以及它们的重载版本。
  4. 编译时会根据实际情况生成特定类型的函数,编译器编译后的最终代码不包含任何模板,只包含为程序生成的实际函数。
    这个根据模板生成特定类型函数定义(模板实例)的过程称为隐式实例化。
  5. 显式实例化:直接命令编译器创建特别的实例。注意区别:显式实例化不template后不包含<>,而显示具体化后面有。
    template void Swap<int> (int, int);

    也可以省略<int>://是否可省略有待验证

    template void Swap(int, int);

    注:显式实例化是用函数模板生成特定类型的模板实例(函数定义);而显式具体化则是要自己写出类型的函数定义。

    隐式实例化 和 显式实例化 和 显式具体化 统称为具体化,表示的都是使用具体类型的函数定义,而不是通用描述。

  6. 注:在同一编程单元中使用同一种类型的显式实例和显式具体化将出错。
  7. 编译器选择最佳匹配模板的原则是找出“最具体”的函数模板:
    非模板函数 > 显式具体化模板函数  >   普通模板函数
    用于找出最具体的模板的规则被称为  函数的部分排序规则
  8. 如果有多个同样合适的非模板函数或模板函数,但没有一个比其它函数更具体,或者没有一个函数匹配 ,这些情况都是错误的。
  9. 编译器在选择最佳匹配函数时,不考虑返回类型,而只考虑函数的特征标。
    对于参数的匹配选择的优先顺序如下:
    完全匹配   >    提升转换(char到int,float到double等)    >         标准转换(int到char,long到double等)      >    用户定义的转换(如类)

学习C++.Primer.Plus 8 函数探幽的更多相关文章

  1. 学习C++.Primer.Plus 7 函数

    C++的返回值类型不能是数组 函数原型中的变量名相当于点位符,因此不要求提供变量名. void cheers(int); C++中不指定参数列表时就使用活力号: void saybye(...); 通 ...

  2. 《C++ Primer Plus》读书笔记之六—函数探幽

    第八章 函数探幽 1.常规函数与内联函数的主要区别不在于编写方式,而在于C++编译器如何将它们组合到程序中. 2.常规函数调用使程序跳到另外一个地址(函数地址),并在函数结束时返回,更详细的的实现过程 ...

  3. C++ primer plus读书笔记——第8章 函数探幽

    第8章 函数探幽 1. 对于内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到一个位置执行代码,再调回来.因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存. 2. 要使用内 ...

  4. 我的MYSQL学习心得(六) 函数

    我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...

  5. 学习之"setjmp和longjmp函数"

    Linux学习之"setjmp和longjmp函数"   转贴,原文地址:http://www.cnblogs.com/lq0729/archive/2011/10/23/2222 ...

  6. Lua和C++交互 学习记录之六:全局函数交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  7. Hadoop源码学习笔记(2) ——进入main函数打印包信息

    Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...

  8. 学习LoadRunner之C语言函数

    学习LoadRunner之C语言函数 Action() { /*strchr和strrchr的区别*/ /* char *strTest1="citms citms"; char ...

  9. Python学习,第八课 - 函数

    本次讲解函数,由于内容比较多,小编列了个大纲,主要有一下内容: 1. 函数基本语法及特性 2. 函数参数 3.局部变量 4. 返回值 5.嵌套函数 6.递归 7.匿名函数 8.高阶函数 9.内置函数 ...

随机推荐

  1. mac 终端 常用指令

    开始正式研究ios 应用开发,由于是从C开始学起,所以学习下常用的mac终端指令,方便后续常用操作. mac 终端 常用指令: 1.ls指令 用途:列出文件 常用参数 -w 以简洁的形式列出所有文件和 ...

  2. BitTorrent Sync - 神奇的文件同步软件,无需服务器让多台电脑互相同步!

    176,487 微博 腾讯 空间 微信 141 49 如今人们对文件备份和同步的需求已经越来越强烈了.像 Dropbox 一样的云存储网盘有很多,但它们都有一个局限性,就是所有的文件都得经过它们的服务 ...

  3. 理解TCP三次握手/四次断开的必要性

    1 TCP的三次握手与必要性 (1)三次握手图 (2)必要性:TCP通过三次握手建立可靠的(确保收到)的全双工通信. 1)第一次握手和第二次握手(ACK部分)建立了从客户端到服务器传送数据的可靠连接: ...

  4. 集合迭代器快速失败行为及CopyOnWriteArrayList

    以下内容基于jdk1.7.0_79源码: 什么是集合迭代器快速失败行为 以ArrayList为例,在多线程并发情况下,如果有一个线程在修改ArrayList集合的结构(插入.移除...),而另一个线程 ...

  5. 利用webview实现在andorid中嵌入swf

    项目背景是这样的,一套系统有三个客户端分别是网页,flex和android,现在已经在flex上面做好了一个在线客户视频聊天系统,然后在这个基础上修改打包成了SWF,放在网页上面使用效果不错,但是利用 ...

  6. [Linux 性能检测工具]FREE

    FREE NAME free显示系统可用内存和已使用内存 语法 free [-b | -k | -m] [-o] [-s delay ] [-t] [-l] [-V] 描述 free显示了总可用和被用 ...

  7. Java并发之CyclicBarrier 可重用同步工具类

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * Cyclic ...

  8. 用自己的算法实现startsWith和endsWith功能。

    String str=new String(); str="erty"; Scanner sc= new Scanner(System.in); System.out.printl ...

  9. 烂泥:【解决】修改LVM卷组名重启系统后,无法进入进入系统

    本文由秀依林枫提供友情赞助,首发于烂泥行天下. 一台服务器系统已经安装完毕,但是LVM的卷组vg使用的是默认的VolGroup名称,使用起来感觉不舒服,打算把这个卷组名称修改为vg. 先来查看系统中有 ...

  10. stm32 USART rs485 rs232

    转载自:http://www.cnblogs.com/chineseboy/archive/2013/03/06/2947173.html 前题: 前段时间,在公司调试了一个项目,很简单,但对于初学的 ...