unique_ptr 提升等效吗?
boost 库中是否有 C++1x 的 std::unique_ptr 的等效类?我正在寻找的行为是能够拥有一个异常安全的工厂函数,就像这样......
std::unique_ptr<Base> create_base()
{
return std::unique_ptr<Base>(new Derived);
}
void some_other_function()
{
std::unique_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is destructed automagically.
}
编辑:现在,我正在使用这个黑客,这似乎是我目前能得到的最好的......
Base* create_base()
{
return new Derived;
}
void some_other_function()
{
boost::scoped_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is deleted automagically.
}
Is there some equivalent class for C++1x's std::unique_ptr in the boost libraries? The behavior I'm looking for is being able to have an exception-safe factory function, like so...
std::unique_ptr<Base> create_base()
{
return std::unique_ptr<Base>(new Derived);
}
void some_other_function()
{
std::unique_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is destructed automagically.
}
EDIT: Right now, I'm using this hack, which seems like the best I can get at this point...
Base* create_base()
{
return new Derived;
}
void some_other_function()
{
boost::scoped_ptr<Base> b = create_base();
// Do some stuff with b that may or may not throw an exception...
// Now b is deleted automagically.
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果没有 C++0x,就不可能创建像
unique_ptr
这样的东西(它是标准库的一部分,因此 Boost 不需要提供它)。特别是如果没有右值引用(C++0x 中的一项功能),无论有或没有 Boost,
unique_ptr
的稳健实现都是不可能的。在 C++03 中,有一些可能的替代方案,尽管每种方案都有其缺陷。
boost::shared_ptr
就功能而言可能是最简单的替代品。您可以在任何需要使用unique_ptr
的地方安全地使用它,并且它可以工作。由于增加了引用计数,它的效率不会那么高。但如果您正在寻找一个简单的替代品,能够处理unique_ptr
可以做的所有事情,这可能是您最好的选择。 (当然,shared_ptr
还可以做更多事情,但它也可以简单地用作unique_ptr
的直接替代品。)boost: :scoped_ptr
与unique_ptr
类似,但不允许转让所有权。只要智能指针在其整个生命周期内保留独占所有权,它就可以很好地工作。std::auto_ptr
的工作方式与unique_ptr
非常相似,但有一些限制,主要是它不能存储在标准库容器中。如果您只是寻找一个允许所有权转移的指针,但并不意味着将其存储在容器中或四处复制,那么这可能是一个不错的选择。It's not possible to create something like
unique_ptr
without C++0x (where it's part of the standard library, and so Boost doesn't need to provide it).Specifically without rvalue references, which are a feature in C++0x, a robust implementation of
unique_ptr
is impossible, with or without Boost.In C++03, there are a few possible alternatives, although each have their flaws.
boost::shared_ptr
is probably the simplest replacement in terms of capabilites. You can safely use it anywhere you'd otherwise use aunique_ptr
and it'd work. It just wouldn't be as efficient, because of the added reference counting. But if you're looking for a simple drop-in replacement that's able to handle everythingunique_ptr
can do, this is probably your best bet. (Of course, ashared_ptr
can do a lot more as well, but it can also simply be used as a drop-in replacement forunique_ptr
.)boost::scoped_ptr
is similar tounique_ptr
but does not allow transfer of ownership. It works great as long as the smart pointer is meant to retain exclusive ownership throughout its lifetime.std::auto_ptr
works very similar tounique_ptr
, but has a few limitations, mainly that it can not be stored in standard library containers. If you're simply looking for a pointer that allows transfer of ownership, but which is not meant to be stored in containers or copied around, this is probably a good bet.从 Boost 1.57 开始,官方有一个< code>unique_ptr 在 Boost.Move 库中实现。
来自文档:
该代码位于
头文件中,并位于boost::movelib
命名空间中。此外,Boost.Move 库在
以及boost::movelib
中提供了make_unique()
工厂函数> 命名空间。因此,问题中的示例可以通过以下方式实现:
请参阅Wandbox 上的实时示例。请注意,代码在 C++98 模式下使用 gcc 4.6.4 可以正常编译(!)。
当将 boost::movelib::unique_ptr 应用于带有基类/派生类的情况时,有趣的是,该实现为基类中的虚拟析构函数的声明提供了编译时检查。如果您碰巧省略了它代码将无法编译(单击“运行(...)”按钮查看编译器错误消息)。
一个小问题是包含来自
boost/move
目录,但代码位于boost::movelib
命名空间中(细微差别但可能很烦人)。另请参阅关于 boost 的线程邮件列表了解更多详情。
感谢 Ion Gaztañaga 提供的这段绝对独特且有用的代码。
Starting from Boost 1.57 there's an official
unique_ptr
implementation in Boost.Move library.From the documentation:
The code is available in
<boost/move/unique_ptr.hpp>
header file and lives inboost::movelib
namespace. Moreover, Boost.Move library providesmake_unique()
factory function in<boost/move/make_unique.hpp>
, also inboost::movelib
namespace.Hence the example from the question could be implemented this way:
See a live example on Wandbox. Note that the code compiles fine with gcc 4.6.4 in C++98 mode (!).
What's interesting in
boost::movelib::unique_ptr
when applied to your case with base/derived classes, the implementation provides a compile-time check for the declaration of a virtual destructor in the base class. If you happen to omit it the code won't compile (click the "Run (...)" button to see the compiler error message).One minor issue is that includes come from
boost/move
directory but the code lives inboost::movelib
namespace (subtle difference but can be annoying).See also a thread on boost mailing list for more details.
Thanks to Ion Gaztañaga for this absolutely unique and useful piece of code.
您可能想尝试 Howard Hinnant 的 C++03 的“概念验证”
unique_ptr<>
实现(免责声明 - 我没有):他的示例之一是返回
unique_ptr
:You might want to try Howard Hinnant's 'proof of concept'
unique_ptr<>
implementation for C++03 (disclaimer - I haven't):One of his examples is returning a
unique_ptr<int>
:怎么样unique_ptr
来自 进程间 图书馆?How about
unique_ptr
from the interprocess library?我用过 Howard Hinnant 的 unique_ptr。如果您不太擅长从编译器中读取疯狂的元编程错误,您可能需要避开。然而,在 90% 的情况下,它的行为就像 unique_ptr 一样。
否则,我建议将参数作为
boost::scoped_ptr&
传递并在内部交换以窃取所有权。要获取 unique_ptr 样式的返回值,请使用auto_ptr
。在shared_ptr
或scoped_ptr
中捕获auto_ptr
返回值,以避免直接使用auto_ptr
。I've used Howard Hinnant's unique_ptr. If you are not really good at reading crazy metaprogramming errors from you compiler you might want to steer clear. It however does act just like a unique_ptr in 90% of the cases.
Otherwise I'd suggest passing paramters as
boost::scoped_ptr&
and swap internally to steal ownership. To get unique_ptr style return values use anauto_ptr
. Capture theauto_ptr
return value in ashared_ptr
orscoped_ptr
to avoid using theauto_ptr
directly.