C++学习笔记2
A Better C
引用
引用是更安全的指针。他类似于变量的一个别名。
定义
int a = 3;
int &b = a;
引用与指针的区别
- 引用不能为空 创建引用时就需要赋值
- 引用不能更改 一旦创建,不能指向其他对象
这样,就解决了野指针等问题。因此引用被称为更安全的指针。
引用作为函数参数
我们经常将指针作为函数参数。既然引用是更安全的指针,自然也可以作为函数参数使用。例如用引用完成两个数的交换
void swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}
是不是比指针的操作简单很多,却又完成了相同的功能。
引用作为函数返回值
一般情况下,我们不会返回指针,因此也几乎不返回引用。但在以下的情境中,引用是可以作为函数返回值的
int &fun(void)
{
static int a = 10;
return a;
}
void main(void)
{
fun() = 20;
}
上述函数将改变静态局部变量a
的值。由于静态局部变量在函数外不可见,这样的方法在某些情况下是有实际用途的,但是并不推荐。
同时我们注意到,fun
的返回值放在了等号左边。这种情况被称作左值。函数返回值很少作为左值,此处即为一个特例。
命名空间
Overloading
函数的重载几乎是所有现代语言必须的特性之一。编程时,一般要求函数名简明扼要的描述函数的功能。但问题是,有时候多个函数的功能高度类似,而c语言却不支持多个函数重名。c++依靠函数重载完美得解决了这个问题。
函数签名
当多个函数重名时如何区分呢?答案是函数签名。函数签名包含了描述一个函数所必须的信息
- 函数名
- 参数类型、个数、顺序等
- 所在类和命名空间
因此当函数命相同时,编译器还是可以通过其他信息来决定究竟调用哪个函数。这里需要注意形参名称不是函数签名的一部分,因为形参名只不过是一种标识符,在函数的每个定义中都是可以改变的。
参数列表
函数声明时可以只给出参数类型的列表,因为形参名在声明时并不重要。有时可能见到函数的参数列表只有一个void
关键字,这代表函数的参数列表为空,不能传入参数。
实际上,不仅仅在函数声明时可以省略形参名,函数定义时也是可以的。例如
void fun(int)
{
cout << "fun called" << endl;
}
int main(int argc, char *argv[])
{
fun(0);
return 0;
}
在调用时,无论向fun
函数中传入什么参数都不会有差别。这种做法可能看起来多此一举,但在一些情况下被用于函数重载。实际开发中,是有可能存在两个函数功能相似且参数列表相同的。这时为了区分两个函数,可以在其中一个的参数列表后加入一个无意义的参数。
默认参数
在函数声明时,可以在形参名后跟一个默认值。用户调用函数时,如果没有显示的传递参数,则这一参数会被赋予默认值参与运算。例如
void fun(int a, int b = 1)
{
// ...
}
int main(int argc, char *argv[])
{
fun(10);
fun(10, 11);
return 0;
}
需要注意以下两点
- 默认参数可以有多个,但必须位于参数列表末尾
- 在函数的多次声明中,只能有一次含默认参数的声明