如何组合std :: make_shared和new(std :: nothrow)

时间:2014-03-19 15:49:26

标签: c++ make-shared nothrow

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

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

(是的,我明白这只会阻止新手抛出bad_alloc;它不会阻止Foo的构造函数抛出异常。)

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:7)

它看起来像allocate_shared,传入一个使用nothrow new的分配器应该可以帮到你。

答案 1 :(得分:1)

只需拥有自定义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>(); }
}