其实在说指针与引用之前得详细的介绍下引用的问题,引用在理解起来其实是一个非常让人苦恼的问题。因为”引用“它的词性理解起来让人特别的烦恼,因为”引用“这个词即是个名词又是个动词。此处的引用到底是什么意思呢?
问题一:什么是引用?
引用(reference):就是对象的另一个名字。(名字是名词,所以此时我们把引用当做一个名词)。引用主要用作函数的形式参数。(作为参数的,那更是名词了)。到此为止,接下来就好理解了,因为它是个名词,对于名词的理解就比动词的理解方便多了。
进一步理解:引用是一种复合类型(引用又是一种类型),通过在变量名前添加”&“符号来定义。复合类型指的是用其他类型来定义的类型。
用事实说话:
int ival = 1024;
int &refVal = ival; //正确,引用必须用与该引用同类型的对象初始化。
int &refVal2; //错误,引用必须初始化
int &refVal3 = 10; //错误,10的类型不确定
结论:其实引用只是一个别名,即只是他绑定的对象的另一个名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上:
<当引用初始化以后,一定要初始化,只要该引用存在,它保持绑定到初始化时指向的对象,不可能将引用绑定到另一个对象上去。>
问题二:引用和指针有什么区别?
上面介绍的是引用初始化的时候就把它指向了一个对象,那么指针也是指向一个对象,那么指针和引用又有什么区别呢?
关于指针:
(1)概念:指针是用于指向对象,具体的来说指针保存的是另一个对象的地址。
(2)定义与初始化:每个指针都有一个与之相关联的数据类型,该数据类型决定了指针所指向的对象的类型。
string *pstring ; //语句把pstring定义为一个指向string类型对象的指针变量
一个有效的指针必然是以下三种状态之一:(2.1)保存一个特定对象的地址
(2.2)指向某个对象后面的另一个对象
(2.3)或者是0值。若指针保存0值,表明不指向任何对象。
(上面提出了有效指针的三种情况,在调试过程中经常遇到”段错误“,其实”段错误”造成的一种原因就是“野指针”,即使用了未初始化的指针,因此要避免使用)
关于二者之间的区别:
(1)非空区别。上面提到了引用必须用与该引用同类型的对象初始化。也就是说一个引用必须指向某些对象。
如果想使用一个变量并让他指向一个对象,但该变量在某些时候也可能不指向任何对象,该怎么做?
这时候尽量使用指针变量,但是不是不初始化,而是让它等于0值,不指向任何对象。
如果你想使用一个变量,且不允许变量为空,该怎么做?
使用引用,因为此时引用比指针的效率要高很多。
(2)合法性区别。在引用使用之前不需要测试它的合法性,但是指针总是被测试,防止其为空。
(3)可修改区别。上面提到了即只是他绑定的对象的另一个名字,作用在引用上的所有操作事实上都是作用在该引用绑定的对象上:但是指针可以被重新赋值以指向另一个不同的对象。
(4)应用区别。
什么时候考虑使用指针?
一是考虑到不指向任何对象的可能
二是能够在不同的时刻指向不同的对象