参考自《More Effective C++》
Pointers和References看起来很不一样(Pointers使用“*”和“->”操作符。而References使用“.”操作符。)但它们似乎做类似的事情。何时该使用哪一个?如何区别它们?
情况一
由于reference必须得代表某个对象,C++因此要求reference必须有初始值:
string& rs; //错误!引用必须被初始化。
string s("xyz");
string& rs = s; //正确
pointers就没有这样的限制
string *ps;
有时候”没有null reference”意味着使用references可能比使用pointers更高效。
因为如果使用pointers,通常在使用前需要测试它是否为null:
void printDouble(const double *pd)
{
if(pd) //检查是否为null
{
cout << *pd;
}
}
而使用reference前不需要测试其有效性:
void printDouble(const double& rd)
{
cout << rd; //不用检查
}
但是应该坚决避免以下这种情况:
char *pc = 0; //将pointer设定为null
char& rc = *pc; //让reference代表这个null pointer
这种结果不可预期,C++对此未作出定义,程序员应该避免写出这种代码。
情况二
当需要考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的需求时,应该选用pointer。
“不指向任何对象”意味着你可以将pointer设置为null。
“在不同时间指向不同对象”意味着你可以改变pointer所指向的对象。
当你确定“总是会代表某个对象”,而且“一旦代表了该对象就不能再改变”,那么你应该选用reference。
string s1("Nancy");
string s2("Mike");
string& rs = s1; //rs代表s1
string *rp = &s1; //ps指向s1
rs = s2; //rs仍代表s1,只是s1的值变为了“Mike”
ps = &s2; //ps现在指向了s2
情况三
当实现某些操作符的时候,需要使用reference。例如:operator[]。
vector<int> v(10); //定义一个int型vector,大小为10;
v[5] = 10; //v[5]即对vector<int> v进行“[]运算”。
//然后把10赋值给“[]运算符”的返回值,即vector<int> v的第5个元素。
//如果operator[]返回pointer,那么上述语句应写成:
*v[5] = 10;
这很不自然,这会让人误以为这是个指针形成的vector。为了避免这中情形,你应该使用reference作为operator[]的返回值类型。
总结:
当你知道你需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由pointers达成,你就应该选择reference。
其他任何时候,请采用pointers。