C++ 如何结合std::make_shared和new(std::nothrow)
C++的新版本提供了一个选项,可以在分配失败时返回一个空指针,而不是抛出一个错误的alloc异常C++ 如何结合std::make_shared和new(std::nothrow),c++,make-shared,nothrow,C++,Make Shared,Nothrow,C++的新版本提供了一个选项,可以在分配失败时返回一个空指针,而不是抛出一个错误的alloc异常 Foo * pf = new(std::nothrow) Foo(1, 2, 3); (是的,我知道这只会阻止new抛出一个坏的alloc;它不会阻止Foo的构造函数抛出一个异常。) 如果您想使用共享指针而不是原始指针,通常应该使用make_shared,因为它可以巧妙地分配控制块 auto pf = std::make_shared<Foo>(1, 2, 3); auto-pf=s
Foo * pf = new(std::nothrow) Foo(1, 2, 3);
(是的,我知道这只会阻止new抛出一个坏的alloc;它不会阻止Foo的构造函数抛出一个异常。)
如果您想使用共享指针而不是原始指针,通常应该使用make_shared,因为它可以巧妙地分配控制块
auto pf = std::make_shared<Foo>(1, 2, 3);
auto-pf=std::使_共享(1,2,3);
make_shared封装了新版本,这使得(?)无法选择nothrow版本。因此,似乎您必须放弃make_shared并显式地调用new
std::shared_ptr<Foo> pf(new(std::nothrow) Foo(1, 2, 3));
std::shared_ptr pf(新的(std::nothrow)Foo(1,2,3));
这消除了使用Foo分配控制块的优化,并且控制块分配可能独立于Foo分配而失败,但我不想重点讨论这个问题。让我们假设控制块很小,因此它的分配在实践中永远不会失败。我关心的是没有为Foo分配空间
有没有一种方法可以获得make_shared的单次分配优势,同时在为Foo分配空间时保留只获取空指针而不是错误的alloc异常的能力?它看起来像
allocate_shared
,传入一个使用nothrow
new的分配器就可以了。只需自定义nake\u 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>(); }
}
#包括
结构Foo{
Foo(int,int,int){throw std::bad_alloc();}
};
std::共享的ptr make_foo(inta、intb、intc){
尝试{return std::make_shared(a,b,c);}
catch(const std::bad_alloc&{return std::shared_ptr();}
}
您可能需要复制一份共享的代码,然后根据需要对其进行修改。注意:投票被否决,因为这将违反分配器的要求。(§17.6.3.5表28)如果系统内存不足,该解决方案肯定会出现严重错误<例如,MSVC12的code>allocate_shared()
不会检查allocate()
返回的指针,并且很乐意在(void*)0
处构造控制块。第一次尝试取消引用此指针很可能会失败。(幸运的是,在MSVC12上,allocate_shared()“内存分配给类型为T的n个对象,但未构造对象。allocate可能会引发适当的异常。”。这无疑不是很明确,但它声明在a.allocate()之后
内存已分配。没有选择不分配并返回nullptr
。在这种情况下,它可能会抛出一个异常,post条件不需要保持。同时,有人询问从何处得出相同的结论。