Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何结合std::make_shared和new(std::nothrow)_C++_Make Shared_Nothrow - Fatal编程技术网

C++ 如何结合std::make_shared和new(std::nothrow)

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

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=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条件不需要保持。同时,有人询问从何处得出相同的结论。