C++ Primer Plus(八)——函数探幽

  1. 程序员将函数作为自己的内联函数时,编译器不一定会满足这种要求。他可能认为函数过大或是函数自己调用了自己,或有些编译器不支持这种特性。

  2. 如果函数定义占用多行,作为内联函数就不太合适。

  3. 必须在声明引用时将其初始化,而不能先声明再赋值,一旦它与某个变量关联起来,就一直效忠于它。

  4. 当且仅当函数参数为const引用时,C++在下列情况下才可能创建临时变量:

    1. 实参的类型正确,但不是左值(左值是指除不被引号括起的字符串和包含多项的表达式外的可引用的数据对象)

    2. 实参的类型不正确,但可以转换为正确的类型

  5. 应尽可能的使用const:

    1. 使用const可以避免无意中修改数据的编程错误

    2. 使用const使函数能够处理const和非const实参,否则只能接受非const数据

    3. 使用const引用使函数能够正确生成并使用临时变量

  6. 返回引用时,应避免返回指向临时变量的指针。要避免这种问题,可以返回一个作为参数传递给函数的引用,也可以用new来分配新的存储空间,但当不再需要new分配的内存时,应使用delete来释放他们,auto_ptr和C++11新增的unique_ptr模板可帮助程序员完成释放工作。

  7. setf( )能设置各种格式化状态,setf(ios_base::fixed)使用定点表示法,方法precision( )指定显示多少位小数;setf(ios_base:showpoint)显示小数点,即使小数部分为0;方法width( )设置下一次输出操作使用的字段宽度,默认为0,这种设置只在显示下一个值时有效,然后恢复到默认。

  8. setf( )返回调用它之前的有效的格式化设置,ios_base::fmtflags是存储这种信息所需的数据类型名称,将它作为参数调用setf( ) ,所有格式化设置恢复到原来的值。

  9. 对于使用传递的值而不修改的函数:

    1. 如果数据对象很小,如内置数据类型或小型结构,则按值传递

    2. 如果数据对象是数组,则使用指针,将指针声明为指向const的指针

    3. 如果数据对象是较大的结构,则使用const指针或const引用,以提高程序的效率

    4. 如果数据对象是类对象,则使用const引用。

  10. 对于修改调用函数中数据的函数:

    1. 如果数据对象是内置数据类型,则使用指针。

    2. 如果数据对象是数组,则使用指针。

    3. 如果数据对象是结构,则使用引用或指针。

    4. 如果数据对象是类对象,则使用引用。

  11. 对于带参数列表的函数,必须从右向左添加默认值,也就是说要为某个参数设置默认值,则必须为他右边的所有参数提供默认值。只有原型制定了默认值,函数定义与没有默认参数时完全一致。

  12. 当函数调用捕鱼任何原型匹配时,没有匹配的原型不会停止使用其中的某个函数,C++会尝试使用标准类型转换进行强制分配。当强制转换后。仅有一个为唯一的原型,C++将调用,当不只一个原型时,C++将拒绝这种调用。

  13. 编译器在检查函数的参数列表时,把类型引用和类型本身视为同一个参数列表。

  14. 如果函数调用存在多个原型匹配,C++将调用最匹配的版本。

  15. 如果在需要多个将同一种算法用于不同类型的函数时,请使用模板。如果不考虑向后兼容的问题,并愿意键入较长的单词,则声明类型参数时,应使用关键字typename而不是class。

  16. 并非所有的模板参数都必须是模板参数类型。

  17. 显示具体化(C++98):

    1. 对于给定函数名,可以有非模板函数、模板函数和显示具体化函数模板及其重载版本

    2. 显示具体化的原型和定义应以template<>打头,并通过名称指出类型,如template<> void swap<int>(int&,int&)或template<> void swap(int&,int&),意思是不要使用swap()模板来生成函数定义,而应使用专门为int类型显示定义的函数定义,这些原型必须要有自己的函数定义

    3. 非模板函数优先于具体化函数,具体化函数优先于常规模板

  18. 显示实例化:声明所需的类型——用<>符号表示类型,并在声明前加上关键字,如template void swap<int>(int ,int),意思是使用swap模板生成int类型定义

  19. 重载解析:

    1. 创建候选函数列表,其中包含与被调用函数名称相同的函数和模板函数。

    2. 使用候选函数列表创建可行函数列表,这些都是函数数目正确的函数,为此有一个饮食转换序列,其中包括实参类型与相应的形参类型完全匹配的情况。

    3. 确定是否有最佳的可行函数。通常,从最佳到最差的顺序:

      1. 完全匹配,常规函数优先于模板

        进行完全匹配时,C++允许某些“无关紧要的转换”:

        从实参到形参
        TypeType&
        Type&Type
        Type[ ]*Type
        Type(argument-list)Type(*)(argument-list)
        Typeconst Type
        Typevolatile Type
        Type *const Type
        Type *volatile Type

        重载解析将寻找最匹配的函数。如果只存在一个这样的函数,则选择它;如果有多个匹配的原型,编译器将无法完成重载解析的过程;然后有时候,即使两个函数完全匹配,仍可完成重载解析。首先,指向非const数据的指针和引用,优先与非const指针和引用参数匹配。一个完全匹配由于另一个的另一种情况是,其中一个是模板函数,另一个不是,在这种情况下,非模板函数优于模板函数。如果两个函数都是模板函数,则较具体的模板函数优先,即他需要进行的转换更少。找出最具体函数的规则被称为函数模板的部分排序规则。

      2. 提升转换

      3. 标准转换

      4. 用户定义的转换

  20. 关键字decltype(C++11):

    decltype(expression) var,为确定类型,编译器必须遍历一个核对表:

    1. 如果expression是一个没有用括号括起来的标识符,则var的类型与该标识符的类型相同,包括const等限定符。

    2. 如果expression是一个函数调用,则var的类型与函数的返回类型相同(并不会实际调用函数)。

    3. 如果expression是一个左值,则var为指向类型的引用,最显而易见的情况是expression是用括号括起来的标识符(括号不会改变表达式的值和左值性)。

    4. 如果前面的条件都不满足,则var类型和expression类型相同。

转载于:https://my.oschina.net/shou1156226/blog/601384

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值