《C++ Primer》读书笔记-第六章 05 特殊用途语言特性

作者:马志峰
链接:https://zhuanlan.zhihu.com/p/23848398
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

声明:

  • 文中内容收集整理自《C++ Primer 中文版 (第5版)》,版权归原书所有。
  • 原书有更加详细、精彩的释义,请大家购买正版书籍进行学习。
  • 本文仅作学习交流使用,禁止任何形式的转载
  • 默认实参
  • 内联函数
  • constexpr函数
  • 调试帮助

默认实参作为形参的初始值出现在形参列表中
如果某个形参被赋予了默认值,它后面的所有形参都必须有默认值
如果在调用时省略了实参,则使用默认实参初始化形参

默认实参声明

允许多次声明同一个函数,给不同的形参添加默认实参
在给定的作用域中,一个形参只能被赋予一次默认实参

string screen( int width, int height, char title = ' ' );  
string screen( int width, int height, char title = '*' );  
string screen( int width = 24, int height = 80, char title );

第二条声明语句是错误的,一个形参只能被赋予一次默认实参
第三条声明语句是正确的,可以看到它并没有再次给title设置默认实参

MZF:

  1. 这里的示例代码对原书进行了修改,说实话原书的示例我没看懂,谁给解释解释?
  2. 没能理解c++支持这种语法有什么用,一次把默认值都声明好不就行了么

默认实参初始值

int wd = 80;  
char def = ' ';  
int ht();  
string screen( int width = ht(), int height = wd, char title = def );  

void f2()  
{  
    def = '*';  
    //def改变了默认实参的值  
    int wd = 100;  
    //wd隐藏了外层定义的wd,但没有改变默认值  
    string window = screen();  
}

下面的两句话很好的解释了这个现象

  1. 用作实参的名字在函数声明所在的作用域内解析
  2. 求值过程发生在函数调用时

也就是说

  1. screen只会找同一作用域内的变量作为实参,所以后来定义的局部变量wd根本是不可见的
  2. 默认实参只是代替了实参,但是初始化形参的时机没有变,还是发生在函数调用时。因此改变全局变量def的值后,默认实参也发生了改变

MZF: 代码同样有少的修改,原书声明函数时不指明形参名,默认实参有什么用?

内联函数

一次函数调用实际包含着一系列工作:

  • 调用前要先保存寄存器,并在返回时恢复
  • 可能要拷贝实参
  • 程序转向一个新的位置继续执行

把函数声明为内联函数可以避免这一系列的开销

函数声明前加上inline关键字就可以了

声明为内联函数后,在编译时将函数在每个调用点上“内联地”展开

扫描二维码关注公众号,回复: 12227480 查看本文章

因为要展开,所以内容长的函数不适合内联

constexpr函数

函数的返回类型必须是字面值类型
所有形参的类型必须是字面值类型

constexpr函数被隐式地指定为内联函数

调试帮助

assert预处理宏

需要引入cassert头文件

assert( expr );

如果表达式的值为假(即0),assert输出信息并终止程序的执行

NDEBUG预处理变量

当然,我们并不会希望程序发布的时候assert也发挥作用,时不时的终止程序的执行

如果定义了NDEBUG,则assert什么也不做

我们也可以编写自己的调试代码

#ifndef NDEBUG  
    cout << "debug" << endl;  
#endif

预处理器还定义了4个对调试很有用的名字

__FILE__  
__LINE__  
__TIME__  
__DATE__

猜你喜欢

转载自blog.csdn.net/qq_26751117/article/details/53319011
今日推荐