这是一篇关于名为Rule of Zero的成语的文章。
这是一段摘录:
class module {
public:
explicit module(std::wstring const& name)
: handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}
// other module related functions go here
private:
using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;
module_handle handle;
};
它重用unique_ptr
了 RAII 功能,因此您无需关心实现令人生畏且冗长的五规则包装器。
以这种方式呈现(以这种方式管理基于句柄的资源unique_ptr
),它对我来说看起来像是一个黑客,而不是它试图解决的最佳解决方案。隐含的假设太多:
- 一个人能够对等并使用
#define
(ortypedef
)HANDLE
所基于的基本类型。对我来说,这应该是隐藏的知识,并且解决方案完全基于界面提供的内容:HANDLE
. - 句柄,可以是任何东西,它们不需要是指针类型。
我想使用这个成语,但在我偶然发现的许多情况下它都不够用。
这个以句柄为中心的 RAII 包装器是否已经完成并可以在一些很酷的库中使用?每个人都在使用这样的工具,我不知道吗?(我认为拥有这样的工具不仅适用于一种,而且适用于许多类型的所有权)
编辑 1
这与平台特定的资源句柄无关,例如,glGenLists
返回一种句柄,它是GLuint
,您应该调用glDeleteLists
它。如前所述,资源句柄不需要是指针类型,也不应该假设这种假设。
编辑 2
在前一个示例中,零规则通过使用已经存在的工具unique_ptr
,显示为句柄管理的一个很好的快捷方式。它需要的额外假设使其不足。正确的假设是您有一个句柄,并且您有一个资源破坏函数,该函数会破坏句柄给出的资源。句柄是 a void *
、 aGLuint
还是什么都无关紧要,更糟糕的是,甚至不需要对等HANDLE
内部类型。出于管理句柄 RAII 方式的目的,如果成语告诉它有好处,并且不能适用于这种情况,我觉得它不好,最后使用给定的工具。
编辑 3
一个说明性的情况是,假设您负责使用新的第 3 方 C 库。它包含一个FooHandle create_foo()
和一个void destroy_foo(FooHandle)
。所以你想,“让我们通过使用零规则来使用 FooHandle”。好的,您可以使用 a unique_ptr
, aunique_ptr
来回答您自己的问题吗?是FooHandle
指针吗?,这样你就可以使用 a unique_ptr
toFooHandle
的不暴露的基本类型了吗?它是一个int
?,以便您可以直接使用它,还是更好地(重新)typedef
像@NicolBolas 在他的回答中所做的事情。对我来说,似乎很清楚,即使在如此微不足道的情况下,unique_ptr
也已经显示出不适合管理资源句柄。
免责声明:
我试图重新表述并更好地表达自己:
编辑 4
我找到了我要找的东西,我把它作为重新制定的问题的答案:https ://stackoverflow.com/a/14902921 。