指针与引用看上去完全差异(指针用操纵符’*’和’->’,引用利用操纵符’.’),可是它们好像有沟通的成果。指针与引用都是让你间接引用其他工具。你如何抉择在什么时候利用指针,在什么时候利用引用呢?
首先,要认识到在任何环境下都不能用指向空值的引用。一个引用必需老是指向某些工具。因此假如你利用一个变量并让它指向一个工具,可是该变量在某些时候也大概不指向任何工具,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,假如变量必定指向一个工具,譬喻你的设计不答允变量为空,这时你就可以把变量声明为引用。
“可是,请等一下”,你猜疑地问,“这样的代码会发生什么样的效果?”
char *pc = 0; // 配置指针为空值
char& rc = *pc; // 让引用指向空值
这长短常有害的,毫无疑问。功效将是不确定的(编译器能发生一些输出,导致任何工作都有大概产生),应该躲开写出这样代码的人除非他们同意纠正错误。假如你担忧这样的代码会呈此刻你的软件里,那么你最好完全制止利用引用,要否则就去让更优秀的措施员去做。我们今后将忽略一个引用指向空值的大概性。
因为引用必定会指向一个工具,在C里,引用应被初始化。
string& rs; // 错误,引用必需被初始化
string s("xyzzy");
string& rs = s; // 正确,rs指向s
指针没有这样的限制。
string *ps; // 未初始化的指针
// 正当但危险
不存在指向空值的引用这个事实意味着利用引用的代码效率比利用指针的要高。因为在利用引用之前不需要测试它的正当性。
void printDouble(const double& rd)
{
cout << rd; // 不需要测试rd,它
} // 必定指向一个double值
相反,指针则应该老是被测试,防备其为空:
void printDouble(const double *pd)
{
if (pd) { // 查抄是否为NULL
cout << *pd;
}
}
指针与引用的另一个重要的差异是指针可以被从头赋值以指向另一个差异的工具。可是引用则老是指向在初始化时被指定的工具,今后不能改变。
string s1("Nancy");
string s2("Clancy");
string& rs = s1; // rs 引用 s1
string *ps = &s1; // ps 指向 s1
rs = s2; // rs 仍旧引用s1,
// 可是 s1的值此刻是
// "Clancy"
ps = &s2; // ps 此刻指向 s2;
// s1 没有改变
总的来说,在以下环境下你应该利用指针,一是你思量到存在不指向任何工具的大概(在这种环境下,你可以或许配置指针为空),二是你需要可以或许在差异的时刻指向差异的工具(在这种环境下,你能改变指针的指向)。假如老是指向一个工具而且一旦指向一个工具后就不会改变指向,那么你应该利用引用。
尚有一种环境,就是当你重载某个操纵符时,你应该利用引用。最普通的例子是操纵符[]。这个操纵符典范的用法是返回一个方针工具,其能被赋值。
vector v(10); // 成立整形向量(vector),巨细为10;
// 向量是一个在尺度C库中的一个模板
v[5] = 10; // 这个被赋值的方针工具就是操纵符[]返回的值
假如操纵符[]返回一个指针,那么后一个语句就得这样写:
*v[5] = 10;
可是这样会使得v看上去象是一个向量指针。因此你会选择让操纵符返回一个引用。
当你知道你必需指向一个工具而且不想改变其指向时,可能在重载操纵符并为防备不须要的语义误解时,你不该该利用指针。而在除此之外的其他环境下,则应利用指针。