2009-08-19 128 views
76

我已经被告知句柄是一种指针,但不是,它允许你保持对一个对象的引用,而不是对象本身。什么是更详细的解释?什么是C++中的句柄?

+6

http://en.wikipedia.org/wiki/Handle_%28computing%29 – Jherico 2009-08-19 23:59:10

+0

看看责任链模式,你会发现“Handle”基本上是一个节点,而“Handler”是他们中的一小部分。 “魔术”来自递归 – 2013-06-26 00:30:35

回答

79

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

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

编辑:不是100%确定你在问题中具体询问什么。这主要是谈论纯粹的C/C++。

+10

句柄可用于保存状态(等等)。如果你有像std :: vector这样的结构中的数据。您的对象可能在程序执行期间的不同时间处于不同的内存位置,这意味着您指向该内存的指针将更改值。使用句柄永远不会改变,它总是引用你的对象。想象一下,保存一个程序的状态(如在游戏中) - 你不会将指针位置保存到数据中,然后再次导入数据并尝试在内存中获取该地址。但是,您可以用数据存储句柄,并导入数据和句柄。 – SinisterRainbow 2012-08-19 15:42:53

+0

是否可以将HANDLE转换为Linux中的等价物?我必须将使用HANDLE的程序从Windows迁移到Linux。 – 2015-11-04 13:33:08

+1

这是正确的答案,它们可以是任何东西,并且使用它们的代码定义了句柄的类型。我试图对自己的类似答案做一个更加简洁的版本,对于后人来说,不能帮助自己。 @CornelVerster - 它们在linux中是一样的。我的意思是,不是OS处理,而是概念。所以,它依赖于处理它的迁移,甚至需要迁移。 – 2017-09-24 22:43:11

4

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

4

这似乎在Handle-Body-Idiom的情况下,也称为平普尔成语。它允许将一个库的ABI(二进制接口)保持一致,方法是将实际数据保存到另一个类对象中,该类对象仅由“句柄”对象中保存的指针引用,其中包含委派给该类的函数“身体”。

启用两个对象的恒定时间和异常安全交换也很有用。为此,仅仅指向正文对象的指针必须交换。

25

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

这将是更准确的说是一个指针是一个句柄类型,但并非所有的句柄是指针。

例如,手柄也可以是一些索引到在存储器中的表,其对应于本身包含一个指向一些对象的条目。

关键的一点是,当你有一个“把柄”,你不知道,也不关心是如何处理实际上结束了识别其所标识的东西,所有你需要知道的是,它的作用。

还应该是显而易见的,没有一个统一的答案,“到底什么是柄”,因为手柄不同的东西,甚至在同一个系统中,可以在“引擎盖下”不同的方式来实现。但你不应该关心这些差异。

+1

你的答案补充了这一点https://stackoverflow.com/a/1923646/2188550 – Ivanzinho 2018-01-17 02:32:19

41

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

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); 
    } 
} 
0
HANDLE hnd; is same as void * ptr; 

HANDLE是在visual studio(windows)的winnt.h文件中定义的一个typefed。

C节:typedef void *HANDLE;

了解更多关于HANDLE

+1

这只适用于Windows,并且只有通过Windows体系结构使用的许多类型的句柄之一。但是,**是**所谓的“正常的Windows应用程序级别句柄”。 – 2017-09-24 22:35:11

0

句柄是你希望它是什么。

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

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

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

使用术语'处理'的原因是重要的。这表明他们是对象的标识或访问类型。这对程序员来说意味着它们代表一个'关键'访问某物。