句柄与指向对象的指针有何不同,为什么我们不能引用引用?
4 回答
句柄通常是对对象的不透明引用。句柄的类型与引用的元素无关。open()
例如,考虑系统调用返回的文件描述符。类型是int
,但它表示打开文件表中的一个条目。int
存储在表中的实际数据与通过使实现不必维护兼容性而返回的数据无关open()
(即,可以透明地重构实际表而不影响用户代码。句柄只能由同一库接口中的函数使用,可以将句柄重新映射回实际对象。
指针是内存中的地址和驻留在该内存位置的对象类型的组合。该值是地址,指针的类型告诉编译器可以通过该指针执行哪些操作,如何解释内存位置。指针是透明的,因为引用的对象具有指针中存在的具体类型。请注意,在某些情况下,指针可以用作句柄(avoid*
是完全不透明的,指向空接口的指针也是不透明的)。
引用是对象的别名。这就是为什么你不能有一个引用的引用:你可以有一个对象的多个别名,但你不能有一个别名的别名。与指针一样,引用是类型化的。在某些情况下,编译器可以将引用实现为在使用时自动取消引用的指针,在某些其他情况下,编译器可以具有没有实际存储的引用。重要的部分是它们是对象的别名,它们必须使用对象进行初始化,并且在初始化后不能重新定位以引用不同的对象。一旦它们被初始化,引用的所有使用都是对真实对象的使用。
甚至问这个问题,“为什么我们不能有一个引用的引用?” 意味着你不明白什么是引用。
引用是对象的另一个名称;而已。如果我有一个对象存储在变量 X 中,我可以创建一个变量 Y,它是对该对象的引用。他们都在谈论同一个对象,那么引用 Y 到底意味着什么?这与引用 X 没有什么不同,因为它们都引用了相同的东西。
就 C++ 语言而言,“句柄”没有定义。一般来说,“句柄”是代表某种资源的某种形式的构造。您可以从一些创建资源的 API 中获取它。您调用将句柄作为参数的函数,以查询或修改资源的状态。当你完成它时,你把它交给其他一些 API 函数。
指针可以是句柄。引用可以是句柄。一个对象可以是一个句柄。整数可以是句柄。这完全取决于实现句柄的系统想要用它做什么。
Ahandle
有时也被称为“魔术饼干”。它只是标识对象的某种不透明类型的值。在某些情况下,它被实现为一个实际的指针,所以如果你将它转换为一个指向正确类型的指针,你可以取消引用它并使用它指向的任何类型的东西。
在其他情况下,它将被实现为指针以外的东西——例如,您可能有一个该类型的对象表,而句柄实际上只是该表的索引。除非你知道表的基地址,否则你不能对索引做很多事情。
C++ 只是说引用引用是不可能的。没有太多“为什么”的方式——如果他们非常想这样做,他们无疑可以允许它(以及引用数组,就此而言)。然而,决定最好限制引用(很多),所以他们就是这样做的。
区别在于上下文。
句柄的基本含义是它在非常有限的上下文中引用某个对象;例如。一个操作系统只能为一个用户或 pid 打开 20 个文件。指针在“内存”的上下文中引用同一个对象。而reference是一个对象的“别名”——它指的是源代码上下文中的一个对象;因此对引用的引用不存在,因为引用已经“是”对象。