C++学习笔记
C++ 学习笔记
关于函数
使用指针处理数组
大多数情况下C++将数组名视为指针。
例外:
1.数组声明用数组名来标记存储位置。
2.对数组名使用sizeof将得到整个数组的长度。
3.将地址运算符&用于数组名时,返回整个数组的地址。
仅在用于函数头或者函数原型中,下面声明的意义相同。
1 | typename *variable; |
将数组作为参数
1.传递数组时,函数将使用原来的数组(即传递的时地址)。
2.通过数组名与指针对应,将数组地址作为参数可以节省复制整个数组所需要的时间与内存。
3.接受数组参数的函数中,对参数名使用sizeof只能得到指针变量的长度。
将const用于指针
1.禁止将const地址赋值给非const指针,因为这样可以通过指针去修改const变量。
2.仅有一层间接关系时,才可以将非const地址或指针赋值给const指针,否则将不安全。
3.尽可能使用const:避免由于无意间修改数据而导致的编程错误;
使用const使得函数可以同时处理const和非const实参;
使用const引用使函数能正确生成并使用临时变量。
1 | const int *p;//指针指向常量 |
函数指针
内联函数
在函数声明(或定义)前加上关键词inline。
1 | inline void inlineFunc(){ |
什么时候使用内联函数?
代码执行时间短,使用内联函数节省函数调用的时间。
不使用使用内联函数的理由
1.代码执行时间长,节省时间不明显。
2.需要多次调用内联函数(每次调用产生一个副本),将占用更多内存。
3.需要递归时(内联函数不能调用自己)。
引用变量
主要用于作为函数的形参。
使用&符号声明引用,声明时必须将其初始化:
1 | int rats; |
引用接近于const指针:
1 | int &mouse=rats; |
返回引用的函数实际上是被引用的变量的别名。
引用与指针的选择:
(使用传递的值而不修改)
1.数据对象很小,按值传递。
2.数据对象是数组,const指针是唯一的选择。
3.数据对象是较大的结构,使用const指针或const引用。
4.数据对象是类对象,使用const引用。
(修改调用函数中数据的函数)
1.内置数据类型,使用指针。
2.数组,只能使用指针。
3.结构,引用或指针。
4.类对象,使用引用。
默认参数
必须通过函数原型来设置默认值:
1 | char* left(const char*str,int n=1); |
对于带参数列表的函数,如果要为某个参数设置默认值,必须为其右边的所有参数提供默认值:
1 | int smart(int n, int i=1, int j=2);//正确 |
函数模板
使用以下例子创建函数模板:
1 | template <typename AnyType> |
使用函数模板并不能缩短可执行程序,它的意义是使生成多个函数定义更简单,更可靠。
模板函数可以进行重载。
显式具体化
当时模板函数被显式具体化后,编译器找到与函数调用匹配的具体化定义时,将使用此定义而不再寻找模板。
1 | struct job |
实例化与具体化
隐式实例化:编译器使用模板为特定类型生成函数定义,得到函数实例。
显式实例化:直接命令编译器创建特定实例。
1 | template void Swap<int> (int, int);//不同于显式具体化,template后不加<> |
显式具体化:使用专门为某种类型显式地定义的函数定义。
隐式实例化,显式实例化,显式具体化统称具体化,他们均表示使用具体类型的函数定义,而非通用描述。
重载解析
函数重载,函数模板,函数模板重载之中,c++通过重载解析确定最适合的函数定义。
匹配选择顺序由好到坏:
1.完全匹配,常规函数优于模板。
2.提升转换。
3.标准转换。
4.用户自定义转换。
注:有两个函数完全匹配是一种错误