先说结论
- 使用指针的情况:
- 存在不指向任何对象的可能
- 需要在不同的时刻指向不同的对象
- 使用引用:
- 必须指向一个对象并且不会改变它的指向
- 重载操作符时
它们的异同
- 相同点
- 指针和引用的功能大致相同:间接引用其他对象
- 不同点
- 表面上看上去完全不同
- 指针操作符为:
*
和->
,引用操作符为:.
- 指针可以为空,引用任何情况下不能为空。下面的代码会导致未定义的行为:
char *pc = 0;
char &rc = *pc; // 引用指向空值
- 因为引用不能为空,所以引用应该被初始化,而指针没有这个要求(未初始化的指针不能直接使用,否则未定义的行为!)
- 因为引用不能为空,所以使用引用前不需要测试它的合法性,效率比指针高(指针在使用前需要判断有效性)
- 指针可以被重新赋值,以指向不同的对象,引用可以理解为初始化对象的别名,它总是指向在初始化时的对象,以后不能改变。如下代码示例:
string s1("foo");
string s2("bar");
string& rs = s1;
string *ps = &s1;
rs = s2; // rs仍引用s1,实际是把s2赋值给s1,所以s1现在的值是 bar
ps = &s2; // ps现在指向s2,s1保持不变
- 重载操作符时,使用引用不会产生语义误解,如:
vector<int> v(10);
v[5] = 10; // 操作符 [] 的返回值为引用,被赋值为10
// 如果操作符 [] 返回指针,语句如下:
*v[5] = 10; // 容易被误解为向量指针
总结
虽然指针和引用的功能相同,但在使用细节上还是有需要思考的地方,混乱使用可能造成严重的后果。
理清它们的区别与联系后,根据实际需要选用即可。
参考资料
《More Effective C++》