C++ 句柄、指针和引用的区别是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13023405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between: Handle, Pointer and Reference
提问by quantum231
How does a handle differ from a pointer to an object and also why can't we have a reference to a reference?
句柄与指向对象的指针有何不同,为什么我们不能拥有对引用的引用?
回答by David Rodríguez - dribeas
A handle is usually an opaquereference to an object. The type of the handle is unrelated to the element referenced. Consider for example a file descriptor returned by open()
system call. The type is int
but it represents an entry in the open files table. The actual data stored in the table is unrelated to the int
that was returned by open()
freeing the implementation from having to maintain compatibility (i.e. the actual table can be refactored transparently without affecting user code. Handles can only be used by functions in the same library interface, that can remap the handle back to the actual object.
句柄通常是对对象的不透明引用。句柄的类型与引用的元素无关。考虑例如open()
系统调用返回的文件描述符。类型是int
但它代表打开文件表中的一个条目。存储在表中的实际数据与int
通过open()
使实现不必维护兼容性而返回的数据无关(即可以透明地重构实际表而不影响用户代码。句柄只能由同一库接口中的函数使用,可以将句柄重新映射回实际对象。
A pointer is the combination of an address in memory and the type of the object that resides in that memory location. The value is the address, the type of the pointer tells the compiler what operations can be performed through that pointer, how to interpret the memory location. Pointers are transparentin that the object referenced has a concrete type that is present from the pointer. Note that in some cases a pointer can serve as a handle (a void*
is fully opaque, a pointer to an empty interface is just as opaque).
指针是内存中的地址和驻留在该内存位置的对象类型的组合。值就是地址,指针的类型告诉编译器通过那个指针可以进行哪些操作,如何解释内存位置。指针是透明的,因为引用的对象具有从指针存在的具体类型。请注意,在某些情况下,指针可以用作句柄(avoid*
是完全不透明的,指向空接口的指针也是不透明的)。
References are aliasesto an object. That is why you cannot have a reference to a reference: you can have multiple aliases for an object, but you cannot have an alias of an alias. As with pointers references are typed. In some circumstances, references can be implemented by the compiler as pointers that are automatically dereferenced on use, in some other cases the compiler can have references that have no actual storage. The important part is that they are aliasesto an object, they must be initialized with an object and cannot be reseated to refer to a different object after they are initialized. Once they are initialized, all uses of the reference are uses of the real object.
引用是对象的别名。这就是为什么你不能有一个引用的引用:你可以有一个对象的多个别名,但你不能有一个别名的别名。与指针引用是类型化的一样。在某些情况下,编译器可以将引用实现为在使用时自动取消引用的指针,在其他一些情况下,编译器可以拥有没有实际存储空间的引用。重要的部分是它们是对象的别名,它们必须用对象初始化,并且在初始化后不能重新设置以引用不同的对象。一旦它们被初始化,所有引用的使用都是真实对象的使用。
回答by Nicol Bolas
To even ask the question, "why can't we have a reference to a reference?" means you don't understand what a reference is.
甚至要问一个问题,“为什么我们不能有一个引用的引用?” 意味着你不明白参考是什么。
A reference is another name for an object; nothing more. If I have an object stored in variable X, I can create a variable Y that is a reference to this object. They're both talking about the same object, so what exactly would it mean to have a reference to Y? It wouldn't be any different from having a reference to X because they're all referencing the same thing.
引用是对象的另一个名称;而已。如果我有一个存储在变量 X 中的对象,我可以创建一个变量 Y 作为对该对象的引用。他们都在谈论同一个对象,那么引用 Y 究竟意味着什么?这与引用 X 没有任何不同,因为它们都引用相同的东西。
A "handle" does not have a definition as far as the C++ language is concerned. Generally speaking, a "handle" is a construct of some form which represents some sort of resource. You get it from some API that creates the resource. You call functions that take the handle as a parameter in order to query the state of the resource or modify it. And when you're done with it, you give it to some other API function.
就 C++ 语言而言,“句柄”没有定义。一般来说,“句柄”是某种形式的构造,代表某种资源。您可以从一些创建资源的 API 中获取它。您调用将句柄作为参数的函数,以查询资源状态或修改它。当你完成它时,你把它交给其他一些 API 函数。
A pointer couldbe a handle. A reference could be a handle. An object could be a handle. An integercould be a handle. It all depends on what the system that implements the handle wants to do with it.
指针可以是句柄。引用可以是句柄。一个对象可以是一个句柄。一个整数可以是一个句柄。这完全取决于实现句柄的系统想要用它做什么。
回答by Jerry Coffin
A handle
is also sometimes called a "magic cookie". Its just a value of some opaque type that identifies an object. In some cases it's implemented as an actual pointer, so if you cast it to a pointer to the correct type, you can dereference it and work with whatever sort of thing it points at.
Ahandle
有时也被称为“魔法饼干”。它只是标识对象的某种不透明类型的值。在某些情况下,它被实现为一个实际的指针,所以如果你将它转换为一个指向正确类型的指针,你可以取消引用它并处理它指向的任何类型的东西。
In other cases, it'll be implemented as something other than a pointer -- for example, you might have a table of objects of that type, and the handle is really just an index into that table. Unless you know the base address of the table, you can't do much of anything with the index.
在其他情况下,它会被实现为指针以外的东西——例如,您可能有一个该类型的对象表,而句柄实际上只是该表的索引。除非你知道表的基地址,否则你不能对索引做任何事情。
C++ simply says that references to references aren't possible. There isn't much in the way of a "why" -- if they'd wanted to badly enough, they undoubtedly could have allowed it (as well as arrays of references, for that matter). The decision was made, however, that it was best to restrict references (a lot), so that's what they did.
C++ 只是说对引用的引用是不可能的。没有太多的“为什么”——如果他们想要足够严重,他们无疑可以允许它(以及引用数组,就此而言)。然而,决定最好限制引用(很多),所以他们就是这样做的。
回答by Aki Suihkonen
The difference is the context.
区别在于上下文。
Basic meaning of a handle is that it refers to some object in very limited context; eg. an OS can keep only 20 files opened for a user or pid. A pointer refers to the same object in the context of "memory". And reference is an "alias" to an object -- it refers to an object in the context of source code; thus reference to a reference doesn't exists as a reference already "is" the object.
句柄的基本含义是它在非常有限的上下文中引用某个对象;例如。操作系统只能为用户或 pid 打开 20 个文件。指针指向“内存”上下文中的同一个对象。引用是对象的“别名”——它指的是源代码上下文中的对象;因此对引用的引用不存在,因为引用已经“是”对象。