You may delay, but time will not.
1 内联函数
1.1 概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。
我们可以在VS下用反汇编查看:
如果在上述函数前增加inline关键字将其改成内联函数,在编译期间编译器会用函数体替换函数的调用。查看方式:
1. 在 release 模式下,查看编译器生成的汇编代码中是否存在 call Add
2. 在 debug 模式下,需要对编译器进行设置,否则不会展开 ( 因为 debug 模式下,编译器默认不会对代码进行优化,以下给出 vs2013 的设置方式 )
1.2 特性
1. inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
前两个都比较好理解,第3个我们可以来试试:
我们再定义一个头文件f.h和一个源文件f.cpp.然后分别放上f方法的声明和定义,最后在编译:
我们发现报了链接错误,这是因为inline被展开,就没有函数地址了,链接就会找不到。
C++用内联函数来解决某些函数压栈的开销,回想C语言,当时我们用的是啥来解决的呢?
那就是宏 (如果忘记了宏可以参考我的这篇文章 程序环境与预处理)
那我们再来简单的回忆下宏的优缺点:
优点:
1. 增强代码的复用性。
2. 提高性能。
缺点:
1. 不方便调试宏。(因为预编译阶段进行了替换)
2. 导致代码可读性差,可维护性差,容易误用。
3. 没有类型安全的检查 。
C++有哪些技术替代宏?
1. 常量定义 换用const
2. 函数定义 换用内联函数
2 auto关键字(C++11)
2.1 auto简介
在早期 C/C++ 中 auto 的含义是:使用 auto 修饰的变量,是具有自动存储器的局部变量 ,但遗憾的是一直没有人去使用它, C++11 中,标准委员会赋予了 auto 全新的含义即: auto 不再是一个存储类型指示符,而是作为一个新的类型 指示符来指示编译器, auto 声明的变量必须由编译器在编译时期推导而得 。
啥意思呢?
我们可以简单的来使用一下:
int main() { auto i = 5; auto d = 3.2; auto c = 'A'; auto s = "abcdef"; cout << typeid(i).name() << endl; cout << typeid(d).name() << endl; cout << typeid(c).name() << endl; cout << typeid(s).name() << endl; return 0; }
其中typeid(XXX).name() 表示求XXX的类型,我们可以来看看结果:
但是typeid(XXX).name()一般是不会显示XXX的const属性的,比如:
无论加不加const我们发现打印出来i的类型都是int 但是我们可以知道在第一种情况下i的类型是const int
【注意】
使用 auto 定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导 auto 的实际类型 。因此 auto 并非是一种 “ 类型 ” 的声明,而是一个类型声明时的 “ 占位符 ” ,编译器在编译期会将 auto 替换为 变量实际的类型 。
但是我们一般都不采取上面的使用方法,而是类型名字很长的时候采用(后面学到vector时就会使用)