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