C++ 从 shared_ptr 中分离指针?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1833356/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detach a pointer from a shared_ptr?
提问by Bj?rn Pollex
Possible Duplicate:
How to release pointer from boost::shared_ptr?
A function of my interface returns a pointer to an object. The user is supposed to take ownership of that object. I do not want to return a Boost.shared_ptr, because I do not want to force clients to use boost. Internally however, I would like to store the pointer in a shared_ptr to prevent memory leaks in case of exceptions etc. There seems to be no way to detach a pointer from a shared pointer. Any ideas here?
我的接口的一个函数返回一个指向对象的指针。用户应该拥有该对象的所有权。我不想返回 Boost.shared_ptr,因为我不想强迫客户端使用 boost。然而,在内部,我想将指针存储在 shared_ptr 中以防止出现异常等情况下的内存泄漏。似乎无法将指针与共享指针分离。这里有什么想法吗?
采纳答案by James McNellis
What you're looking for is a release
function; shared_ptr
doesn't have a release function. Per the Boost manual:
你要找的是一个release
函数;shared_ptr
没有释放功能。 根据 Boost 手册:
Q. Why doesn't shared_ptr provide a release() function?
A. shared_ptr cannot give away ownership unless it's unique() because the other copy will still destroy the object.
Consider:
问:为什么 shared_ptr 不提供 release() 函数?
A. shared_ptr 不能放弃所有权,除非它是 unique() 因为另一个副本仍然会破坏对象。
考虑:
shared_ptr<int> a(new int);
shared_ptr<int> b(a); // a.use_count() == b.use_count() == 2
int * p = a.release();
// Who owns p now? b will still call delete on it in its destructor.
Furthermore, the pointer returned by release() would be difficult to deallocate reliably, as the source shared_ptr could have been created with a custom deleter.
此外,release() 返回的指针将难以可靠地解除分配,因为源 shared_ptr 可能已使用自定义删除器创建。
Two options you might consider:
您可能会考虑两种选择:
- You could use
std::tr1::shared_ptr
, which would require your users to use a C++ library implementation supporting TR1 orto use Boost; at least this would give them the option between the two. - You could implement your own
boost::shared_ptr
-like shared pointer and use that on your external interfaces.
- 您可以使用
std::tr1::shared_ptr
,这将要求您的用户使用支持 TR1 的 C++ 库实现或使用 Boost;至少这会让他们在两者之间做出选择。 - 您可以实现自己的
boost::shared_ptr
类似共享指针,并在您的外部接口上使用它。
You might also look at the discussion at this question about using boost::shared_ptr in a library's public interface.
您还可以查看有关在库的公共接口中使用 boost::shared_ptr 的问题的讨论。
回答by Magnus
there's always a way :-)
总有办法:-)
There is indeed a reason why they don't provide a release() method, but it's not impossible to create one. Make your own deleter. Something on the line of (haven't actually compiled the code, but this is the general notion):
他们不提供 release() 方法确实是有原因的,但创建一个也不是不可能。制作自己的删除器。关于(实际上并没有编译代码,但这是一般概念)的内容:
template <typename T>
class release_deleter{
public:
release_deleter() : released_(new some_atomic_bool(false)){}
void release() {released_->set(true);}
void operator()(T* ptr){if(!released_->get()) delete ptr;}
private:
shared_ptr<some_atomic_bool> released_;
}
..
shared_ptr<some_type> ptr(new some_type, release_deleter<some_type>());
..
release_deleter<some_type>* deleter = get_deleter<release_deleter<some_type>>(ptr);
deleter->release();
some_type* released_ptr = ptr.get();
回答by éric Malenfant
The user is supposed to take ownership of that object. I do not want to return a Boost.shared_ptr,
用户应该拥有该对象的所有权。我不想返回 Boost.shared_ptr,
shared_ptr
expresses sharedownership, and you want your interface to express transferof ownership. std::auto_ptr
would thus be more applicable here.
shared_ptr
表示共享所有权,并且您希望您的界面表示所有权的转移。std::auto_ptr
因此在这里更适用。
Internally however, I would like to store the pointer in a shared_ptr to prevent memory leaks in case of exceptions
但是在内部,我想将指针存储在 shared_ptr 中以防止出现异常时的内存泄漏
Again, shared_ptr
may not be the best tool for that job. To prevent leaks in the case of exceptions, scoped_ptr
or auto_ptr
would be better suited.
同样,shared_ptr
可能不是该工作的最佳工具。以防万一出现泄漏,scoped_ptr
还是auto_ptr
比较适合的。
回答by Ben Voigt
Use a shared_ptr
to a scoped_ptr
to the resource (shared_ptr<scoped_ptr<Resource>>
). That way you get shared_ptr
's reference counting, which will automatically destroy the resource if and only if it's still attached to the scoped_ptr
. But you can detach the scoped_ptr
when you're ready to hand off ownership.
对资源 ( )使用 ashared_ptr
到 a 。这样你就得到了的引用计数,当且仅当它仍然附加到. 但是当您准备好移交所有权时,您可以分离。scoped_ptr
shared_ptr<scoped_ptr<Resource>>
shared_ptr
scoped_ptr
scoped_ptr
回答by philsquared
As James has well covered you can't really detach a shared pointer.
正如 James 已经很好地介绍的那样,您无法真正分离共享指针。
Do you need multiple owners internally, or are you transferring ownership from your class to the client? In that case a std::auto_ptr
might fit the bill.
您内部是否需要多个所有者,或者您是否将所有权从您的班级转移到客户?在这种情况下,astd::auto_ptr
可能符合要求。
If you're worried about the surprising semantics of std::auto_ptr
, you could hold it internally by boost::scoped_ptr
, and detach it at the point you hand it out - leaving it up to the client to manually delete it or store it in their own smart pointer.
如果您担心 的令人惊讶的语义std::auto_ptr
,您可以在内部通过 保存它boost::scoped_ptr
,并在您分发它时将其分离 - 由客户端手动删除它或将其存储在他们自己的智能指针中。
If you do have multiple owners on your side you could use an intrusive count. Internally you could then use boost::intrusive__ptr
, but hand off the raw pointer at the interface. The client can then either manually work with ref counts, or store it in a boost::intrusive_ptr
themselves (but you don't make them depend on it)
如果您身边确实有多个所有者,则可以使用侵入式计数。然后您可以在内部使用boost::intrusive__ptr
,但在接口处传递原始指针。然后,客户端可以手动处理引用计数,也可以将其存储在boost::intrusive_ptr
自己的a 中(但不要让它们依赖于它)