- 微信搜索:编程笔记本
- 微信搜索:编程笔记本
- 微信搜索:编程笔记本
点击上方蓝字关注我,我们一起学编程
欢迎小伙伴们分享、转载、私信、赞赏
小伙伴儿们看完以后可不可以帮我点亮一下在看呀~
指针(pointers)与引用(references)
pointers 和 references 看起来很不一样(pointers 使用 *
和 ->
操作符,references 则使用 .
),但它们似乎在做类似的事情。不论 pointers 或是 references 都使你得间接参考其他对象。那么,何时使用哪一个,你心中可有一把尺?
首先你必须认知一点,**没有所谓的 null reference 。**一个 reference 必须始终代表某个对象。所以如果你有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表)任何对象,那么你应该使用 pointer ,因为你可以将 pointer 设为 null 。换个角度看,如果这个变量总是必须代表一个对象,也就是说如果你的设计并不允许这个变量为 null ,那么你应该使用 reference 。
我们来看看下面的代码,底层意义是什么呢?
char *pc = nullptr; // 将 pointer 设定为 nullptr
char &rc = *pc; // 让 reference 代表 pointer 的解引用值
显然,这是有害的行为,其结果未定义,编译器可以产生任何可能的输出。写出这种代码的人,应该与大众隔离,知道他们允诺不再有类似行为。从现在起,我们将永远不再考虑 “ reference 成为 nullptr ”的可能性。
由于 reference 一定得代表某个对象,因此 C++ 要求 reference 必须有初值:
string &re; // 错误!reference 必须被初始化
string s("abc");
string &rs = s; // 没问题,rs 代表 s
但是 pointer 就没有这样的限制:
string *ps; // 未初始化的指针,有效,但风险高
“没有所谓的 null reference” 这个事实意味使用 reference 可能会比使用 pointer 更富效率。这是因为使用 reference 之前不需要测试其有效性:
void printDouble(const double &rd)
{
cout << rd; // 不需要测试 rd ,它一定代表某个 double
}
- 微信搜索:编程笔记本
- 微信搜索:编程笔记本
- 微信搜索:编程笔记本
如果使用 pointer ,通常就得测试它是否为 null :
void printDouble(const double *pd)
{
if (pd != nullptr) {
cout << *pd;
}
}
pointer 和 reference 之间的另一个重要差异就是,pointer 可以被重新赋值,指向另一个对象,reference 却总是指向(代表)它最初获得的那个对象。
string s1("hello");
string s2("world");
string &rs = s1; // rs 代表 s1
string *ps = &s1; // ps 指向 s1
rs = s2; // rs 仍代表 s1 ,但其值已变为 "world"
ps = &s2; // ps 现指向 s2,s1 未变化
一般而言,当你需要考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的能力时,你就应该采用 pointer 。前一种情况你可以将 pointer 设为 null ,后一种情况你可以改变 pointer 所指对象。而当你确定“总是会代表某个对象”,而且“一旦代表了该对象就不能够再改变”,那么你应该选用 reference 。
还有其他情况也需要使用 reference ,例如当你实现某些操作符的时候。最常见的例子就是 operator[]
。这个操作符很特别,其必须返回某种“能够被当作 assignment” 赋值对象 的东西:
vector<int> v(10);
v[5] = 10; // assignment 的赋值对象是 operator[] 的返回值
如果 operator[]
返回一个 pointer ,上述最后一个语句就必须写成这个样子:
*v[5] = 10;
但这使 v
看起来好像是个指针形成的 vector ,事实上它不是。为了这个因素,你应该总是令 operator[]
返回一个 reference。(也有一个例外,后面讲到的时候我再链接回来)
因此,让我做下结论:当你知道你需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法要求无法由 pointer 达成,你就应该选择 reference 。其他任何时候,请采用 pointer 。
- 微信搜索:编程笔记本
- 微信搜索:编程笔记本
- 微信搜索:编程笔记本