我正在尝试编写一个基于Alexandrescu概念但使用c ++ 11习语的简单ScopeGuard.
namespace RAII
{
template< typename Lambda >
class ScopeGuard
{
mutable bool committed;
Lambda rollbackLambda;
public:
ScopeGuard( const Lambda& _l) : committed(false) , rollbackLambda(_l) {}
template< typename AdquireLambda >
ScopeGuard( const AdquireLambda& _al , const Lambda& _l) : committed(false) , rollbackLambda(_l)
{
_al();
}
~ScopeGuard()
{
if (!committed)
rollbackLambda();
}
inline void commit() const { committed = true; }
};
template< typename aLambda , typename rLambda>
const ScopeGuard< rLambda >& makeScopeGuard( const aLambda& …Run Code Online (Sandbox Code Playgroud) 这篇文章讨论了一个名为"零度规则"的成语.
这是一段摘录:
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;
};
Run Code Online (Sandbox Code Playgroud)
它重用了unique_ptrRAII功能,因此您无需关心实现令人生畏和冗长的Rule of Five包装器.
以这种方式呈现(以这种方式管理基于句柄的资源unique_ptr),它看起来像是一个黑客,而不是它试图解决的最佳解决方案.隐含地假设了太多的假设:
#define(或typedef)HANDLE构建的基本类型.对我来说,这应该是隐藏的知识,而解决方案完全基于界面提供的内容:HANDLE.我想用这个成语,但在我偶然发现的许多情况下都不尽如人意.
这个手柄是否集中了RAII包装器已经完成并可以在一些很酷的库中使用?每个人都使用这样的工具,我不知道吗?(我觉得很高兴有这样的工具不仅适用于一个,而且适用于许多类型的所有权)
这不是关于平台特定的资源句柄,例如,glGenLists返回一种句柄,它是一个GLuint,你应该调用glDeleteLists它.如前所述,资源句柄不需要是指针类型,不应假设这种假设.
在前一个示例中,使用现有工具的Zero of Zero unique_ptr显示为句柄管理的一个很好的捷径.它所需的额外假设使其不足.正确的假设是你有一个句柄,你有一个资源破坏功能,破坏句柄给出的资源.无论句柄是a void …
在范围退出上运行lambda似乎是一个基本的东西,我希望它是标准化的.unique_ptr当它们适用时,情况会更好,但我发现需要无穷无尽的"一次性"析构函数,特别是在利用C风格的库时.有谁知道这是否会到来?
我的印象是它是由第三方编写的库中包含的C++类.我尝试在Google上搜索,我发现有一篇帖子说使用它是个好主意.但是,它未能准确描述它是什么以及如何将其合并到我的代码中.谢谢.
我想知道,STL(C++ 11,C++ 14,...)或者Boost或者其他一些库是否包含这样一个类的实现?所以我可以在不重新实现每个新项目的情况下使用它.
除指针外,句柄具有适当的语义。所以对我来说这样的例子(从零规则中提取):
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;
};
Run Code Online (Sandbox Code Playgroud)
使用unique_ptr作为用于把手的所有权-在级封装“是一个坏的例子。首先,它利用内部知识,即句柄是指针类型,并使用它使unique_ptr“不透明”句柄类型建立在基本类型上。
句柄可以是任何类型,它们可能是一个指针,它们可能是一个索引或谁知道。最重要的是,您手头上的(例如来自大多数 C API)是一个句柄及其资源释放函数。
是否有适用于句柄语义的适当的“包内所有权” ?我的意思是,已经公开可供使用?
对我来说,unique_ptr等。阿尔。不起作用,我必须对句柄类型是什么做出不必要的假设,当我想要的只是通过不透明的句柄类型及其释放功能获得“包中的所有权”时。
通过查看句柄类型内部来构建此信息是没有意义的。这是一个手柄,应该没有关系。
创建一个特定的“智能指针”类,不会花很长时间。不要滥用图书馆课程。句柄语义与 C++ 指针的语义完全不同;一方面,取消引用 HANDLE 是没有意义的。
使用自定义智能句柄类的另一个原因 - NULL 并不总是意味着空句柄。有时是 INVALID_HANDLE_VALUE,这是不一样的。
免责声明:
这个问题重新表述并建立在这个问题的基础上: