unique_ptr 提升等效吗?

发布于 2024-09-04 00:17:39 字数 720 浏览 9 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

稚然 2024-09-11 00:17:39

如果没有 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_ptrunique_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 a unique_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 everything unique_ptr can do, this is probably your best bet. (Of course, a shared_ptr can do a lot more as well, but it can also simply be used as a drop-in replacement for unique_ptr.)
  • boost::scoped_ptr is similar to unique_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 to unique_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.
我是男神闪亮亮 2024-09-11 00:17:39

Boost 1.57 开始,官方有一个< code>unique_ptr 在 Boost.Move 库中实现。

来自文档

(...) std::unique_ptr 的直接替代品,也可在 C++03 中使用
编译器。

该代码位于 头文件中,并位于 boost::movelib 命名空间中。此外,Boost.Move 库在 以及 boost::movelib 中提供了 make_unique() 工厂函数> 命名空间。

因此,问题中的示例可以通过以下方式实现:

#include <boost/move/unique_ptr.hpp>

using boost::movelib::unique_ptr;

unique_ptr<Base> create_base()
{
    return unique_ptr<Base>(new Derived);
}

请参阅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:

(...) a drop-in replacement for std::unique_ptr, usable also from C++03
compilers.

The code is available in <boost/move/unique_ptr.hpp> header file and lives in boost::movelib namespace. Moreover, Boost.Move library provides make_unique() factory function in <boost/move/make_unique.hpp>, also in boost::movelib namespace.

Hence the example from the question could be implemented this way:

#include <boost/move/unique_ptr.hpp>

using boost::movelib::unique_ptr;

unique_ptr<Base> create_base()
{
    return unique_ptr<Base>(new Derived);
}

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 in boost::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.

我很OK 2024-09-11 00:17:39

您可能想尝试 Howard Hinnant 的 C++03 的“概念验证”unique_ptr<> 实现(免责声明 - 我没有):

他的示例之一是返回 unique_ptr

unique_ptr<int> factory(int i)
{
    return unique_ptr<int>(new int(i));
}

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<int> factory(int i)
{
    return unique_ptr<int>(new int(i));
}
空气里的味道 2024-09-11 00:17:39

怎么样unique_ptr 来自 进程间 图书馆?

How about unique_ptr from the interprocess library?

幼儿园老大 2024-09-11 00:17:39

我用过 Howard Hinnant 的 unique_ptr。如果您不太擅长从编译器中读取疯狂的元编程错误,您可能需要避开。然而,在 90% 的情况下,它的行为就像 unique_ptr 一样。

否则,我建议将参数作为 boost::scoped_ptr& 传递并在内部交换以窃取所有权。要获取 unique_ptr 样式的返回值,请使用 auto_ptr。在 shared_ptrscoped_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 an auto_ptr. Capture the auto_ptr return value in a shared_ptr or scoped_ptr to avoid using the auto_ptr directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文