Handles如何妥善管理?

时间:2013-06-19 08:08:18

标签: c++ handle

这是关于正确使用手柄的一个非常基本的问题。给出以下代码(它不是特定的源文件):

typedef void* HANDLE;

HANDLE myHandle;

myHandle = SomeObject;

//...some elaborate code...//
  1. 第一个问题:myHandle现在位于堆栈还是堆?由于Handle可以是一个指针,也只是一个索引,我不太确定。

    在myHandle超出范围时,它被移除(至少我认为是这样)。但是如果它是一个类成员,它将保持可见,直到拥有对象被删除。所以第二个问题:

  2. 如果我想避免进一步访问myHandle,那么这是不错的做法

    myHandle = 0;  // I do not need this handle anymore
    

    我现在会遇到与内存管理的冲突,还是有关托管代码的任何其他限制?是否还有其他选项可以说明此句柄不应再与指针类似使用了:

    mypointer = NULL;
    
  3. 编辑:我首先谈论的是垃圾收集,这显然不包含在c ++中。这是managed extensions的一部分。谢谢你帮我解决了这个致命的错误!

3 个答案:

答案 0 :(得分:1)

由于您没有指定您正在谈论的HANDLE,我假设Windows处理。

HANDLE是一种不透明的数据类型(主要代表操作系统可以使用的数字),并且只能由CreateFileCloseHandle等系统功能处理。 / p>

当您丢失相关资源时,不应自行将HANDLE设置为0

请参阅CloseHandleCreateFile(尤其是返回值)和Windows Data Types

来自Wikipedia

  

在计算机编程中,句柄是对资源的抽象引用。当应用程序软件引用由其他系统(例如数据库或操作系统)管理的内存块或对象时,将使用句柄。

     

虽然指针字面上包含它引用的项的地址,但句柄是外部管理的引用的抽象;它的不透明性允许系统将引用对象重新定位到内存中而不会使句柄无效,这对于指针来说是不可能的。额外的间接层还增加了管理系统对指示对象执行的操作的控制。通常,句柄是一个索引或指向全局逻辑删除数组的指针。


C ++没有标准的垃圾收集,这就是你需要自己删除new ed对象的原因,而不是系统给出的句柄!

答案 1 :(得分:1)

您可能是您所做假设的Java程序员。

变量myHandle确实是在堆栈上分配的,当它超出范围时会被删除,尽管不是垃圾收集器(C ++中不存在这样的东西)。

但是,释放句柄(myHandle只是一个包含一些不透明数值的变量,实际句柄由操作系统拥有 - 因此它的寿命与持有该值的任意变量的寿命不同。您必须使用适当的API函数自己执行此操作(对于HANDLE的大多数事情,这是CLoseHandle),最好使用“句柄持有者”类,因此它是异常安全的。

这种手柄支架的简单实现可能如下所示:

class AutoHandle
{
    HANDLE handle;
public:
    AutoHandle(HANDLE in) : handle(in) {}
    ~AutoHandle() { CloseHandle(handle); }
};

这样,您在打开资源时分配给AutoHandle变量,当它超出范围时,句柄将关闭。你不能忘记这样做,如果发生异常,它甚至会起作用。

答案 2 :(得分:0)

通常更喜欢在将指针指向NULL之前使用delete。

但对于一个HANDLER,请不要自己把它变成NULL!