条款1:仔细区别指针(pointers)和引用(references)

本文讲述了C++中指针和引用的区别,包括空引用不存在但有空指针、引用绑定后不可修改而指针可变、以及在实现操作符如operator[]时的选择。推荐在确定代表固定对象且不变时使用reference,其他情况下优先考虑pointer。
摘要由CSDN通过智能技术生成

声明

指针对应的英文单词是pointer,引用对应的是reference

在英文中,当我们提到多个同一类型的对象时,我们通常会在这个对象名称后面加上“s”来表示复数形式。对于“pointer”和“reference”这两个词来说,也是如此。

当你看到“pointers”时,它表示的是多个指针。例如,在编程中,你可能会有多个指针变量,每个都指向内存中的不同位置。同样地,“references”表示的是多个引用。

所以,加“s”是为了表示这些概念在数量上是多个,而不是单个。

指针和引用

pointers 和references 看起来很不一样(pointers 使用“*”和“>”操作符,references则使用“.”),但它们似乎做类似的事情。不论pointers 或是references都使你得间接参考其他对象。

那么,何时使用哪一个?你心中可有一把尺?

区别1——没有空引用,但有空指针

首先你必须认知一点,没有所谓的null reference。

一个reference必须总代表某个对象。所以如果你有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表)任何对象,那么你应该使用pointer,因为你可以将pointer设为null。

换个角度看,如果这个变量总是必须代表一个对象,也就是说如果你的设计并不允许这个变量为null,那么你应该使用reference。

“但是等等”你说,“下面这样的东西,底层意义是什么呢?”

char *pc = 0;//将 pointer 设定为null。
char& rc = *pc;//让 reference 代表null pointer 的解引值。

哦,这是有害的行为,其结果不可预期(C++对此没有定义),编译器可以产生任何可能的输出,而写出这种代码的人,应该与大众隔离,直到他们允诺不再有类似行为。

如果你在你的软件中还需担心这类事情,我建议你还是完全不要使用references的好,要不就是另请一个比较高明的程序员来负责这类事情。从现在起,我们将永远不再考虑“reference 成为null”的可能性。

由于reference 一定得代表某个对象,C++因此要求references必须有初值:

string& rs;//错误!references 必须被初始化。

string s("xyzzy");
string& rs = s;//没问题,rs指向s。

但是pointers 就没有这样的限制:

string *ps;
//未初始化的指针,有效,但风险高。

“没有所谓的null reference”这个事实意味使用references可能会比使用pointers更富效率。这是因为使用reference 之前不需要测试其有效性:

void printDouble(const double& rd)
{
cout << rd;
// 不需要测试rd,它一定代表某个double。
}

如果使用 pointers,通常就得测试它是否为null:

void printDouble(const double *pd)
{
if (pd) 
cout << *pd;
//检查是否为 null pointer。
}

区别2——引用一旦绑定不可修改,而指针可以

Pointers和references之间的另一个重要差异就是,pointers 可以被重新赋值,指向另一个对象,reference却总是指向(代表)它最初获得的那个对象:

string s1("Nancy");
string s2("Clancy");

string& rs= sl;//rs 代表s1。
string *ps= &s1;// ps 指向 s1。

rs =s2;//rs 仍然代表s1,
// 但是s1的值现在变成了“Clancy”。

ps= &s2;
// ps 现在指向 s2,
//s1没有变化。

一般而言,当你需要考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的能力时,你就应该采用pointer。前一种情况你可以将pointer设为null,后一种情况你可以改变pointer 所指对象。而当你确定“总是会代表某个对象”,而且“一旦代表了该对象就不能够再改变”,那么你应该选用reference。

还有其他情况也需要使用reference,例如当你实现某些操作符的时候。

最常见的例子就是operator[]。这个操作符很特别地必须返回某种“能够被当做assignment 赋值对象”的东西:

vector<int> v(10);
// 产生一个 int vector,大小为10。
// vector 是C++标准程序库
//提供的一个template。

v[5] =10;
// assignment 的赋值对象是operator[]的返回值。

如果operator[]返回pointer,上述最后一个语句就必须写成这样子:
 

*v[5] =10;

但这使v看起来好像是个以指针形成的vector,事实上它不是。为了这个因素,你应该总是令operator[]返回一个reference。

因此,让我做下结论:

  1. 当你知道你需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由pointers达成,你就应该选择references。
  2. 任何其他时候,请采用pointers。
  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值