指针和引用的区别

来源:互联网 发布:淘宝可以贷款么 编辑:程序博客网 时间:2024/06/05 16:35

相同点

  1. 都是地址的概念,引用的本质是指针常量

不同点

  1. 指针是一个变量,这个变量所存的内容是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已,即引用是某块内存的别名
  2. 指针可以有顶层const和底层const,而引用只有底层const。(引用的本质)
  3. 指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
  4. 指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
  5. 指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。(指针随心所欲,引用一成不变)
  6. “sizeof引用”得到的是所指向的变量(对象)的大小,而”sizeof指针”得到的是指针本身的大小;
  7. 指针和引用的自增(++)运算意义不一样;
  8. 作为参数传递时有不同,建议用引用

联系

1.引用的本质是指针常量,因此指针可以做任何引用可以做到的事情,那么为什么我们还需要引用?

摘自「MoreEffective C++」
指针与引用,在MoreEffective C++ 的条款一有详细讲述
条款一:指针与引用的区别
指针与引用看上去完全不同(指针用操作符‘*’和‘->’,引用使用操作符‘&’),但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何决定在什么时候使用指针,在什么时候使用引用呢?
首先,要认识到在任何情况下都不能用指向空值的引用。一个引用必须总是指向某些对象。因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量。相反,如果变量肯定指向一个对象,例如你的设计不允许变量为空,这时你就可以把变量声明为引用。
“但是,请等一下”,你怀疑地问,“这样的代码会产生什么样的后果?”

 char *pc = 0// 设置指针为空值    char& rc = *pc;// 让引用指向空值

产生错误:引发了异常: 读取访问权限冲突。rc 是 nullptr。(VS2017 32bits debug)

2.不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用引用之前不需要测试它的合法性。

void printDouble(const double& rd){     cout << rd; // 不需要测试rd} // 肯定指向一个double值相反,指针则应该总是被测试,防止其为空:void printDouble(const double *pd){     if (pd)     { // 检查是否为NULL           cout << *pd;     }}

3.指针与引用的另一个重要的不同是指针可以被重新赋值以指向另一个不同的对象。但是引用则总是指向在初始化时被指定的对象,以后不能改变。

string s1("Nancy");string s2("Clancy");string& rs = s1; // rs 引用 s1string *ps = &s1; // ps 指向 s1rs = s2; // rs 仍旧引用s1,// 但是 s1的值现在是// "Clancy"ps = &s2; // ps 现在指向 s2;// s1 没有改变

总的来说,在以下情况下你应该使用指针,一是你考虑到存在不指向任何对象的可能(在这种情况下,你能够设置指针为空),二是你需要能够在不同的时刻指向不同的对象(在这种情况下,你能改变指针的指向)。如果总是指向一个对象并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[].这个操作符典型的用法是返回一个目标对象,其能被赋值。
还有一种情况,就是当你重载某个操作符时,你应该使用引用。最普通的例子是操作符[].这个操作符典型的用法是返回一个目标对象,其能被赋值。

 vector<int> v(10); // 建立整形向量(vector),大小为10;// 向量是一个在标准C库中的一个模板(见条款35)v[5] = 10; // 这个被赋值的目标对象就是操作符[]返回的值//如果操作符[]返回一个指针,那么后一个语句就得这样写:*v[5] = 10;
但是这样会使得v看上去象是一个向量指针。因此你会选择让操作符返回一个引用。(这有一个有趣的例外,参见条款30)

当你知道你必须指向一个对象并且不想改变其指向时,或者在重载操作符并为防止不必要的语义误解时,你不应该使用指针。而在除此之外的其他情况下,则应使用指针假设你有

void func(int* p, int&r);int a = 1;int b = 1;func(&a,b);

指针本身的值(地址值)是以passby value进行的,你能改变地址值,但这并不会改变指针所指向的变量的值,
p = someotherpointer;//a is still 1
但能用指针来改变指针所指向的变量的值,
*p = 123131; // a now is 123131
但引用本身是以pass byreference进行的,改变其值即改变引用所对应的变量的值
r = 1231;// b now is 1231
尽可能使用引用,不得已时使用指针。
当你不需要“重新指向”时,引用一般优先于指针被选用。这通常意味着引用用于类的公有接口时更有用。引用出现的典型场合是对象的表面,而指针用于对象内部。
上述的例外情况是函数的参数或返回值需要一个“临界”的引用时。这时通常最好返回/获取一个指针,并使用 NULL 指针来完成这个特殊的使命。(引用应该总是对象的别名,而不是被解除引用的NULL 指针)。
注意:由于在调用者的代码处,无法提供清晰的的引用语义,所以传统的 C 程序员有时并不喜欢引用。然而,当有了一些 C++ 经验后,你会很快认识到这是信息隐藏的一种形式,它是有益的而不是有害的。就如同,程序员应该针对要解决的问题写代码,而不是机器本身。
参考文献
C++引用与指针的区别(着重理解):
http://blog.csdn.net/thisispan/article/details/7456169
浅谈C++中指针和引用的区别:
http://www.cnblogs.com/dolphin0520/archive/2011/04/03/2004869.html
C++引用的本质:
http://blog.csdn.net/qq_22365361/article/details/74011720#t2

原创粉丝点击