在Windows中是否有某种NULL Handle? 如果我通过CreateCompatibleBitmap()
创build一个bmp并通过DeleteObject()
删除它,并想使用移动语义,我想确保位图不被破坏。 因此,我必须将HBITMAP
设置为一个可以安全删除的值。 像delete nullptr
。
首先是坏消息。 由于历史原因,Windows API中没有一般有效的“无效句柄”值。 Windows中的不同子系统将NULL
或INVALID_HANDLE_VALUE
视为无效句柄值(无论是否返回无效句柄值)。 关于旧新事物的相关文章 。
然而, 好消息是,尽管您仍然需要为意外的返回值做准备(除非您为每一个使用的功能挖掘文档),但在实践中提供无效的值仍然是“有效的”。
您可能没有使用正确的指定“无效”值,但它仍然是无效的,因此功能将失败。 您的应用程序不会崩溃,除了浪费了几个CPU周期之外,没有负面影响。
因此,继续使用NULL
(或nullptr
),你很好。 如果没有别的,稍后有人阅读你的代码会很直观。 在具体的例子中, 这也是正确的 ,因为GDI函数假定NULL
是无效的。
几乎可以依靠NULL
和INVALID_HANDLE_VALUE
都是无效的值。 虽然我没有意识到一个要求(如在文档中明确指出的),一个有效的HANDLE
必须是非零的,但实际上他们总是这样。 我敢打赌,你不会找到一个值为零的句柄(只要尝试使用Sysinternals的handle
工具,在你的电脑上没有一个单独的进程可能会有一个低于20的句柄)。
但是,即使假设NULL
可以是一个有效的句柄值,也不得不考虑在调用main
或全局构造函数之前已经打开和关闭了一些句柄,但实际上并没有选择。 这意味着,假设NULL
可以是一个有效的句柄,并且在程序运行的时候仍然有效,那么这个假设的句柄实际上是与API函数兼容的类型的机会是非常低的。
另一方面,有人可能会争辩说,应用程序可能(unsigned) -1
处理打开,呈现INVALID_HANDLE_VALUE
有效的值。
除非你泄漏手柄,否则我无法想象你将如何得到那么多打开的手柄。 但更重要的是,在达到这个数字之前,你可能会在64位系统上耗尽内存,并且你将在32位系统上明确地耗尽地址空间。
如果INVALID_HANDLE_VALUE
是一个有效的句柄成为问题,你有一个更严重的问题。
没有这样的安全价值。 除了一个有效的HGDIOBJ
,特别是一个“逻辑笔,画笔,字体,位图,区域或调色板的句柄”,传递给DeleteObject
中断合同,并可能导致程序崩溃。 或者它可能会进入调试器,特别是在检查的操作系统版本。 或者它可以填充您的硬盘上的日志消息。 或者它可能会导致AppVerifier失败并阻止徽标认证。 或者它可能会触发您的过程的“appcompat”规则,并禁用新的Windows功能“向后兼容性”。 不要这样做。
您可以使用0
作为占位符,但测试该值并且不要在您的句柄为0
调用DeleteObject
。 这与if (p) delete p;
,前面的测试被认为是代码的浪费。
通常0是一个无效句柄,类似于一个空指针。
例如, CreateBitmap
返回0作为无效的位图句柄,如果失败。
因此,您可以安全地使用nullhandle调用DeleteObject
。
从DeleteObject
的文档 :
如果指定的句柄无效或当前被选入DC,则返回值为零。
此例外是一个文件句柄,由CreateFile
返回,其中INVALID_HANDLE_VALUE
被定义为-1
。