我使用RAII通过自定义删除器使用std::unique_ptr
来管理代码中的资源。到目前为止,这一点相对简单,但我现在想为资源添加一个RAII包装器,该资源需要访问现有的托管资源作为其清理函数的一部分。
为了将其分解,我有一个类具有RAII管理的资源,并且可以获取依赖于它的其他资源:
struct CloseHandleFunctor
{
typedef HANDLE pointer;
void operator()(const HANDLE h)
{
::CloseHandle(h);
}
};
using AutoHandle = std::unique_ptr<HANDLE, CloseHandleFunctor>;
class Helper
{
public:
// acquires a resource associated with h_
Resource get_resource();
// releases the resource acquired by get_resource()
void release_resource(const Resource res);
// ...
private:
AutoHandle h_;
};
我想包装Resource
返回的Helper::get_resource()
,但无法解决如何使用std::unique_ptr
提供对Helper
实例的访问权限仿函数中的类:
struct ReleaseResourceFunctor
{
typedef Resource pointer;
void operator()(Helper h, const Resource r)
{
h.release_resource(r);
}
};
using AutoResource = std::unique_ptr<Resource, ReleaseResourceFunctor>;
// no way to pass the instance of Helper ~~~^
这就是我想用它的方式:
int main()
{
Helper h;
{
AutoResource res(h.get_resource());
}
// h.release_resource() gets called
}
答案 0 :(得分:0)
根据Joachim和Casey的建议,我可以通过在函数中存储指向Helper
类实例的指针来实现它:
struct ReleaseResourceFunctor
{
typedef Resource pointer;
Helper *helper_;
ReleaseResourceFunctor()
: helper_(nullptr)
{
}
void setHelper(Helper * const h)
{
helper_ = h;
}
void operator()(const Resource r)
{
if (helper_ != nullptr)
{
helper_->release_resource(r);
}
}
};
...然后在构造std::unique_ptr
之后指定帮助器实例:
int main()
{
Helper h;
{
AutoResource res(h.get_resource());
res.get_deleter().setHelper(&h);
}
// h.release_resource() gets called as expected
}
它似乎有点脆弱(记得每次都分配帮助器实例),但它确实按预期工作。