前言
记得学生时,第一次面试腾讯,面试官问什么是引用。那时的自己还是埋头刷算法,不懂八股文,只能说引用是别名。许多年过去了,我应该能回答这个问题了吧。
指针和引用
指针真是C++里一个神奇的东西,我觉的指针就是存放地址的变量,本质上指针自身还是一个变量。
void Pointer(int* pointer) {
pointer = nullptr;
}
int main() {
int* p = new int(100);
Pointer(p);
assert(p == nullptr);
}
有些人会这样写代码,他们认为指针就是对象本身,但其实是不对的。在函数中pointer已经经历了一次拷贝,所谓的赋值仅仅是将那个局部变量置空了。
我们换种写法
void Pointer(int* &pointer) {
pointer = nullptr;
}
这样是成功的,因为我们传的是引用。
更有意思的一点是下面这个,我觉得能看懂这个就能很好理解指针的含义了:
void Pointer(int** pointer) {
*pointer = nullptr;
}
int main() {
int* p = new int(100);
Pointer(&p);
assert(p == nullptr);
}
其实我们传的是一个二级指针,指向指针的指针。在函数内同样有一次拷贝,但那是最外层的。我们解引用,就指向了main函数中变量,置空即可达到效果。
言归正传,不论是pointers或是references,都使我们能够间接参考其他对象。但何时使用哪一个呢?
- 如果有一个变量,其目的是用来指向另一个对象,但是也有可能不指向任何对象,那么应该使用pointer,因为可以把pointer置为nullptr。如果这个变量必须代表一个对象,也就是说你的设计并不允许为null,那么应该使用reference。
char* pc = nullptr;
char& rc = *pc;
这样的写法感觉就是比较反人类的写法了。
- 基于1,reference一定得代表某个对象, C++因此要求reference必须有初值。
string& rs; // invalid
- pointers可以被重新赋值,指向另一个对象,reference却总是指向它最初获得的那个对象。
- 当实现操作符的时候,可能也是要用reference。最常见的就是operator[]。这个操作符很特别地必须返回某种“能够被当做assignment赋值对象”的东西:
vector<int> v;
v[5] = 10;