作者:马志峰
链接: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:
- 这里的示例代码对原书进行了修改,说实话原书的示例我没看懂,谁给解释解释?
- 没能理解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();
}
下面的两句话很好的解释了这个现象
- 用作实参的名字在函数声明所在的作用域内解析
- 求值过程发生在函数调用时
也就是说
- screen只会找同一作用域内的变量作为实参,所以后来定义的局部变量wd根本是不可见的
- 默认实参只是代替了实参,但是初始化形参的时机没有变,还是发生在函数调用时。因此改变全局变量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__
链接: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:
- 这里的示例代码对原书进行了修改,说实话原书的示例我没看懂,谁给解释解释?
- 没能理解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();
}
下面的两句话很好的解释了这个现象
- 用作实参的名字在函数声明所在的作用域内解析
- 求值过程发生在函数调用时
也就是说
- screen只会找同一作用域内的变量作为实参,所以后来定义的局部变量wd根本是不可见的
- 默认实参只是代替了实参,但是初始化形参的时机没有变,还是发生在函数调用时。因此改变全局变量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__