C++ 学习笔记

关于函数

使用指针处理数组

大多数情况下C++将数组名视为指针。

例外:

1.数组声明用数组名来标记存储位置。

2.对数组名使用sizeof将得到整个数组的长度。

3.将地址运算符&用于数组名时,返回整个数组的地址。

仅在用于函数头或者函数原型中,下面声明的意义相同。

1
2
typename *variable;
typename variable[];

将数组作为参数

1.传递数组时,函数将使用原来的数组(即传递的时地址)。

2.通过数组名与指针对应,将数组地址作为参数可以节省复制整个数组所需要的时间与内存。

3.接受数组参数的函数中,对参数名使用sizeof只能得到指针变量的长度。

将const用于指针

1.禁止将const地址赋值给非const指针,因为这样可以通过指针去修改const变量。

2.仅有一层间接关系时,才可以将非const地址或指针赋值给const指针,否则将不安全。

3.尽可能使用const:避免由于无意间修改数据而导致的编程错误;

使用const使得函数可以同时处理const和非const实参;

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

1
2
const int *p;//指针指向常量
int const *p;//指针本身是常量

函数指针

内联函数

在函数声明(或定义)前加上关键词inline。

1
2
3
inline void inlineFunc(){
cout<<"This is a inline function."<<endl;
}

什么时候使用内联函数?

代码执行时间短,使用内联函数节省函数调用的时间。

不使用使用内联函数的理由

1.代码执行时间长,节省时间不明显。

2.需要多次调用内联函数(每次调用产生一个副本),将占用更多内存。

3.需要递归时(内联函数不能调用自己)。

引用变量

主要用于作为函数的形参。

使用&符号声明引用,声明时必须将其初始化:

1
2
int rats;
int &mouse=rats;//mouse为rats的引用,他们指向同样的值与内存单元

引用接近于const指针:

1
2
3
int &mouse=rats;
int* const pr=&rats;
//mouse扮演的角色与*pr相同

返回引用的函数实际上是被引用的变量的别名。

引用与指针的选择

(使用传递的值而不修改)

1.数据对象很小,按值传递。

2.数据对象是数组,const指针是唯一的选择。

3.数据对象是较大的结构,使用const指针或const引用。

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

(修改调用函数中数据的函数)

1.内置数据类型,使用指针。

2.数组,只能使用指针。

3.结构,引用或指针。

4.类对象,使用引用。

默认参数

必须通过函数原型来设置默认值:

1
char* left(const char*str,int n=1)

对于带参数列表的函数,如果要为某个参数设置默认值,必须为其右边的所有参数提供默认值:

1
2
int smart(int n, int i=1, int j=2);//正确
int fool(int n, int i=1, int j);//错误

函数模板

使用以下例子创建函数模板:

1
2
3
4
5
6
7
8
template <typename AnyType>
void Swap(AnyType &a, AnyType &b)//大量代码库使用关键字class开发,在这种上下文中class与typename等价
{
AnyType temp;
temp=a;
a=b;
b=temp;
}

使用函数模板并不能缩短可执行程序,它的意义是使生成多个函数定义更简单,更可靠。

模板函数可以进行重载。

显式具体化

当时模板函数被显式具体化后,编译器找到与函数调用匹配的具体化定义时,将使用此定义而不再寻找模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
struct job
{
char name[40];
double salary;
int floor;
};
//非模板函数原型
void Swap(job&, job&);
//模板函数原型
template <typename T>
void Swap(T &a,T &b);
//显式具体化
template<> void Swap<job>(job&, job&);

实例化与具体化

隐式实例化:编译器使用模板为特定类型生成函数定义,得到函数实例。

显式实例化:直接命令编译器创建特定实例。

1
template void Swap<int> (int, int);//不同于显式具体化,template后不加<>

显式具体化:使用专门为某种类型显式地定义的函数定义。

隐式实例化,显式实例化,显式具体化统称具体化,他们均表示使用具体类型的函数定义,而非通用描述。

重载解析

函数重载,函数模板,函数模板重载之中,c++通过重载解析确定最适合的函数定义。

匹配选择顺序由好到坏:

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

2.提升转换。

3.标准转换。

4.用户自定义转换。

注:有两个函数完全匹配是一种错误

内存模型

名称空间