什么是C ++中的句柄?

时间:2009-08-19 23:13:24

标签: c++ handle

我被告知句柄是一种指针,但不是,并且它允许您保持对对象的引用,而不是对象本身。什么是更精细的解释?

8 个答案:

答案 0 :(得分:89)

句柄可以是从整数索引到指向内核空间中资源的指针。这个想法是它们提供了资源的抽象,所以你不需要了解资源本身就可以使用它。

例如,Win32 API中的HWND是Window的句柄。它本身就没用了:你无法收集它的任何信息。但是将它传递给正确的API函数,你可以用它执行大量不同的技巧。在内部,您可以将HWND视为GUI窗口表的索引(可能不一定是它的实现方式,但它使魔法变得有意义。)

编辑:不是100%肯定你在问题中具体提到的内容。这主要是谈论纯C / C ++。

答案 1 :(得分:43)

句柄是一个没有可见类型的指针或索引。通常你会看到类似的东西:

 typedef void* HANDLE;
 HANDLE myHandleToSomething = CreateSomething();

因此,在您的代码中,您只需将HANDLE作为不透明值传递。

在使用该对象的代码中,它将指针强制转换为实际结构类型并使用它:

 int doSomething(HANDLE s, int a, int b) {
     Something* something = reinterpret_cast<Something*>(s);
     return something->doit(a, b);
 }

或者它将它用作数组/向量的索引:

 int doSomething(HANDLE s, int a, int b) {
     int index = (int)s;
     try {
         Something& something = vecSomething[index];
         return something.doit(a, b);
     } catch (boundscheck& e) {
         throw SomethingException(INVALID_HANDLE);
     }
 }

答案 2 :(得分:26)

句柄一种指针,因为它通常是一种引用某个实体的方式。

更准确地说,指针是一种句柄,但并非所有句柄都是指针。

例如,句柄也可能是内存表中的一些索引,它对应于一个本身包含指向某个对象的指针的条目。

关键是当你有一个“句柄”时,你既不知道也不关心这个句柄最终如何识别它识别的东西,你需要知道的就是它。

显而易见的是,对于“究竟是什么样的句柄”没有单一的答案,因为即使在同一系统中,对不同事物的处理也可以在“引擎盖下”以不同的方式实现。但你不应该担心这些差异。

答案 3 :(得分:5)

在C ++ / CLI中,句柄是指向位于GC堆上的对象的指针。使用new在(非托管)C ++堆上创建对象,new表达式的结果是“普通”指针。使用gcnew表达式在GC(托管)堆上分配托管对象。结果将是一个句柄。你不能在句柄上做指针运算。你没有释放句柄。 GC会照顾他们。此外,GC可以自由地重新定位托管堆上的对象,并在程序运行时更新句柄以指向新位置。

答案 4 :(得分:5)

这出现在Handle-Body-Idiom的上下文中,也称为Pimpl习语。它允许通过将实际数据保存到另一个类对象中来保持库的ABI(二进制接口)相同,该对象仅由“句柄”对象中保存的指针引用,该指针由委托给该类的函数组成。身体”。

启用两个对象的常量时间和异常安全交换也很有用。为此,只需要交换指向body对象的指针。

答案 5 :(得分:1)

HANDLE hnd;void * ptr;

相同

HANDLE是Visual Studio(Windows)中winnt.h文件中定义的typedef:

typedef void *HANDLE;

详细了解HANDLE

答案 6 :(得分:1)

句柄是你想要的任何东西。

句柄可以是某些查找表中使用的无符号整数。

句柄可以是指向更大数据集的指针。

这取决于使用句柄的代码的行为方式。这决定了句柄类型。

使用术语“句柄”的原因很重要。这表明它们是对象的标识或访问类型。这意味着,对于程序员来说,它们代表了对某些内容的“关键”访问权限。

答案 7 :(得分:0)

指针是句柄的一个特例。指针的好处是它直接在内存中标识一个对象,代价是对象变得不可重定位。句柄抽象出内存中对象的位置,但需要额外的上下文来访问它。例如,将句柄定义为数组索引,我们需要一个数组基指针来计算项目的地址。有时上下文在调用站点是隐含的,例如当对象池是全局的。这允许优化手柄的大小和使用,例如16 位 int 而不是 64 位指针。