引用
例子
指针是最简单的引用,由于和底层硬件的亲密关系,使其成为最强大及有效的引用之一。不过,也因为此一关系,程序员在使用指针时,必须非常了解内存架构的细节。因为指针存储内存的地址,而非直接存储值,不正常地使用指针会导致程序出现未定义行为。智能指针是一个非透明指针,作用和指针相似,但只能通过特定方式访问。
句柄是一种抽象引用,可用许多不同方法呈现。其中一个常见的例子为文件句柄(用于C语言标准输入/输出库中的文件数据结构 ),用来描述抽象的文件内容。文件句柄通常可用来表示文件本身(当要求该文件的锁时),以及文件内容中的某一特定位置(当读存该文件时)。
在分布式计算中,引用可能包含一个以上的地址或识别字;也可能包括用来定位或访问引用对象之网络协议的编码格式,用来说明消息被编码或序列化之方式。举例来说,WSDL中对远程网络服务的描述可被视为一种引用,包括如何定位及绑定特定Web服务之完整格式。另一个例子为对即使分布式对象的引用:该引用为一个如何建设称之为“代理(proxy)”之小型软件组件的完整格式,此代理接着会运行点对点(peer-to-peer)的交互,并使本地机器得以访问被复装或只存在部分一致之消息流的数据。
编程语言的支持性
在第一个被使用的编程语言-汇编语言中,一般使用未处理的内存地址或数组中的索引表示引用。这样使用是可行的,但有点微妙,因为一个地址无法告诉你它指向的值是什么,更不用说这个值有多大,或是该如何解释;此类消息都内含在程序的逻辑之中。如此一来,误解将可能出现在不正确的程序里,引发令人感到困惑的错误。
最早的不透明引用为LISP的 cons 函数,此一函数只是一个包含两个引用至其他Lisp对象的记录,其他Lisp对象也可能包括其他的cons函数。此一简单的结构最常被用来建构单向链表,但也可用来建构简单的二叉树,以及一种被称为“点状串列”的结构,该结构最终会终止于一个值上,而非空引用。
另一个早期的语言-Fortran则没有明确用来表示引用的用法,但可以传引用调用的方式使用引用。
指针依然是今日最常见的一种引用,类似于汇编语言中对未处理内存地址的表示方式,不同之处在于指针带有一个固定之数据类型,可在编译期间用来确保所指之数据不被误解。不过,因为C语言有个可以使用类型转换(在不同指针类型间及指针类型与整数间转换)的弱类型系统,虽然较为困难,但还是有可能误解。C++试图在C++标准程序库中使用新的cast运算符及较聪明的指针,以增加类型安全;但为了兼容性,仍保留绕过这些安全机制的能力。
许多今日常见的主流语言,如Eiffel、Java、C#及Visual Basic等,则均采用了一种更加不透明的引用,通常即简称为“引用”。此类引用具有类似C语言指针的类型,会指出其所引用数据的意思;不过,此类引用为类型安全的,无法指向一个未处理的地址,以及进行不被允许的不安全转换。
引用与指针的区别
对于同时支持引用与指针的C/C++,两类数据型的区别有:
指针可以重新赋值,而引用在初始化绑定后就不能再绑定到其他对象。
指针对象有它自己的内存地址与内存长度,而引用与它指向的对象具有相同的内存地址、内存长度。因此,可以把引用看作是被指向对象的另一个名字。
指针可以指向另一指针,因此允许多层的指针间址(indirection);而引用只允许到对象的一层间址,不允许“引用的引用”。
指针可以直接赋值为NULL,引用不能。当然,可以费劲办法把引用绑定到内存的NULL上,但这并不实用。
指针可以在数组上遍历(iterate),引用不能。
指针需要用运算符“*”来解引用(dereference)以访问它所指向的内存的内容;引用需要显式的解引用。指向类/结构的指针访问成员变量/成员函数需要用运算符->而引用使用运算符.来访问成员。
指针是一个变量,保存了内存地址;而C/C++标准都没有明说引用是如何实现的。实际上,几乎所有C/C++编译器把引用作为一个隐式的指针来实现。
指针可以成为数组的成员类型,即指针数组;但引用不可以作为数组的成员类型,即不存在“引用数组”。
const引用可以绑定到临时对象;而指针不能(例如, int *y = 12; 编译出错)。按照C++11语法,const左值引用可以绑定到一切对象,包括const左值对象,非const左值对象,const临时对象,非const临时对象;右值引用当然可以绑定到临时对象。
参考文献
参见
抽象化 (计算机科学)
变量 (程序设计)
弱引用
免责声明:以上内容版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。感谢每一位辛勤著写的作者,感谢每一位的分享。
- 有价值
- 一般般
- 没价值