我只想在不使用shared_ptr部分的情况下使用shared_ptr的删除功能。就像在,我想在shared_ptr超出范围并且删除器不需要传递给它的任何指针时调用一个函数。
我有这个,但它很腼腆。
shared_ptr<int> x(new int, [&](int *me) { delete me; CloseResource(); });
有没有办法不将任何指针与shared_ptr关联?
更新:根据许多建议,unique_ptr方式如下所示:
unique_ptr<int, std::function<void(int*)>> x(new int, [&](int *me) {delete me; CloseResource();});
坦率地看起来比shared_ptr版本更糟糕,尽可能多“好”。
更新:对于那些喜欢使用这个简单范围关闭函数调用者的人,我使它更简单一点,你甚至不需要分配或释放一个对象:
shared_ptr<int> x(NULL, [&](int *) { CloseResource(); });
答案 0 :(得分:3)
听起来你可能试图做的就是翻身&#34;删除&#34;对#34;其他人的责任&#34;所以你再也不用担心了。如果是这种情况,使用自定义删除工具的unique_ptr
(不是shared_ptr
)将有效:
struct Foo final {};
Foo* New() { return new Foo; }
void Delete(Foo* p) { delete p; }
int main()
{
auto p = New();
std::unique_ptr<Foo, decltype(&Delete)> up(p, &Delete);
}
列出了许多类似的解决方案here;如果没有关于您的实际API的更多信息(例如,HANDLE
is really a pointer技巧是否有效?),可以做的更多。甚至更多阅读The simplest and neatest c++11 ScopeGuard,包括建议std::unique_resource
的{{3}}。
答案 1 :(得分:0)
如果你想要一个像lambda这样语义的RAII可能会有这样的工作吗?
namespace details {
enum class ScopeExitDummy { };
}
template<typename T>
class scope_exit_t
{
public:
inline scope_exit_t(T&& codeChunk_)
: m_codeChunk(std::forward<T>(codeChunk_)) {
}
inline scope_exit_t(scope_exit_t<T>&& rhs_)
: m_codeChunk(std::move(rhs_.m_codeChunk))
{
}
~scope_exit_t() {
m_codeChunk();
}
private:
T m_codeChunk;
};
template<typename T>
inline scope_exit_t<T> operator+(details::ScopeExitDummy, T&& functor_) {
return scope_exit_t<T>{std::forward<T>(functor_)};
}
#define AtScopeExit auto TW_UNIQUE_VARIABLE(_scopeExit) = details::ScopeExitDummy{} + [&]
用法如下:
AtScopeExit {
CloseResource();
};
注意:TW_UNIQUE_VARIABLE只是一个生成唯一变量名的宏,因此代码不会与手写声明冲突。
#define TW_STR_CONCAT_IMPL(x, y) x##y
#define TW_STR_CONCAT(x, y) TW_STR_CONCAT_IMPL(x, y)
#ifdef __COUNTER__
#define TW_UNIQUE_VARIABLE(prefix) TW_STR_CONCAT(prefix, __COUNTER__)
#else
#define TW_UNIQUE_VARIABLE(prefix) TW_STR_CONCAT(prefix, __LINE__)
#endif