16

C++ 的 new 可以选择在分配失败时返回空指针,而不是抛出 bad_alloc 异常。

Foo * pf = new(std::nothrow) Foo(1, 2, 3);

(是的,我知道这只会阻止 new 抛出 bad_alloc;它不会阻止 Foo 的构造函数抛出异常。)

如果你想使用共享指针而不是原始指针,你通常应该使用 make_shared,因为它对控制块的分配很聪明。

auto pf = std::make_shared<Foo>(1, 2, 3);

make_shared 封装了新的,这使得(?)无法选择 nothrow 版本。因此,您似乎必须放弃 make_shared 并明确调用 new 。

std::shared_ptr<Foo> pf(new(std::nothrow) Foo(1, 2, 3));

这消除了使用 Foo 分配控制块的优化,并且控制块分配可能会独立于 Foo 分配而失败,但我不想关注这一点。让我们假设控制块很小,因此它的分配在实践中永远不会失败。我担心的是未能为 Foo 分配空间。

有没有办法获得 make_shared 的单一分配优势,同时在为 Foo 分配空间时保留简单地获取空指针而不是 bad_alloc 异常的能力?

4

2 回答 2

6

看起来allocate_shared,传入一个使用nothrownew 的分配器应该可以为您解决问题。

于 2014-03-19T16:23:12.800 回答
2

只需自定义 nake_foo 并捕获异常:

#include <memory>

struct Foo {
    Foo(int, int, int) { throw std::bad_alloc(); }
};

std::shared_ptr<Foo> make_foo(int a, int b, int c) {
    try { return std::make_shared<Foo>(a, b, c); }
    catch (const std::bad_alloc&) { return std::shared_ptr<Foo>(); }
}
于 2014-03-19T16:23:56.087 回答