Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.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_*而不是构造函数更好?_C++_C++11_Std - Fatal编程技术网

C++ 为什么使用std::make_*而不是构造函数更好?

C++ 为什么使用std::make_*而不是构造函数更好?,c++,c++11,std,C++,C++11,Std,STL中有一些以make_前缀开头的函数,如std::make_pair、std::make_shared、std::make_unique等。为什么使用它们比简单使用构造函数更好 auto pair2 = std::pair< int, double >( 1, 2.0 ); auto pair3 = std::make_pair( 1, 2.0 ); std::shared_ptr< int > pointer1 = std::shared_ptr< int

STL中有一些以
make_
前缀开头的函数,如
std::make_pair
std::make_shared
std::make_unique
等。为什么使用它们比简单使用构造函数更好

auto pair2 = std::pair< int, double >( 1, 2.0 );
auto pair3 = std::make_pair( 1, 2.0 );

std::shared_ptr< int > pointer1 = std::shared_ptr< int >( new int( 10 ) );
std::shared_ptr< int > pointer2 = std::make_shared< int >( 10 );
auto-pair2=std::pair(1,2.0);
自动配对3=std::make_配对(1,2.0);
std::shared_ptrpointer1=std::shared_ptr(新的int(10));
std::shared_ptrpointer2=std::make_shared(10);
  • 我只是看到这些函数使代码缩短了一点,但就这些吗
  • 还有其他优势吗
  • 这些功能使用起来更安全吗

尽管这可能是主观的,但这种技术的一个主要好处是:

针对接口而不是实现编写代码

本质上,函数模板实例化根据传递的参数执行类型推断,而类模板实例化则不执行。因此,您不必像直接实例化类时那样传递模板参数

但是应该注意的是,这不是关于“保存几个字符”,而是关于使代码更通用,避免在函数调用中绑定到具体类型

但是,情况并非总是如此,正如您的
std::make_shared
示例所示,仍然存在必须将类型作为模板参数传递的情况。但是,正如所述,在使用
std::make_shared
时还有其他几个优点:

  • 你应该先写清楚和正确,而
    std::make_shared
    实现了这两个目标(主观的,但我同意)

  • 使用
    std::make_shared
    效率更高,因为它可以一次性分配对象和
    shared_ptr
    对象,从而降低分配开销和更好的缓存对齐


  • make_unique
    对您隐藏“原始”指针,这通常是一件好事-它不太容易出错。
    make_shared
    可以改善
    shared_ptr
    实例的内存分配。通常,当您使用
    shared_ptr
    构造函数时,它将分配内存两次,第一次分配内存,例如
    X
    ,第二次分配内存,用于内部数据(例如参考计数器)
    make_shared
    启用优化-它将创建单个内部结构,包括
    X
    和引用计数器,因此它将执行单个内存分配。和以前一样,它隐藏原始指针。

    除了启用参数推断的好处(如其他答案中所述),还有一些其他好处

    std::make_-pair
    注意不要简单地返回
    std::pair
    。如果使用
    std::ref
    传入一个值,则返回的对不会存储
    std::reference\u包装
    ,它将存储一个引用

    std::make_shared
    可以合并分配
    shared_ptr
    需要一个地方来存放refcount、弱指针列表等不能直接存储在
    shared_ptr
    中的内容。这些可以与正在创建的对象组合在一个稍大的块中,而不是两个单独的块中


    std::make_shared
    std::make_unique
    都确保在抛出异常时不会留下任何对象。如果将函数调用为
    f(std::shared_ptr(new int)、std::shared_ptr(new int))
    ,那么编译器可能首先分配两个
    int
    对象,然后构造两个
    shared_ptr
    对象。如果第二次分配失败,并且没有设置任何
    shared_ptr
    对象以在销毁时释放内存,则表示内存泄漏
    std::make_shared
    std::make_unique
    在函数调用中结合
    int
    的分配和
    std::shared_ptr
    的构造,在另一个函数调用中结合
    int
    的其他分配和
    std::shared_ptr
    的其他构造。函数调用不能重叠,因此,如果第二次分配失败,则已经有一个共享指针将被销毁,第一次分配也将被撤消。

    对于新的智能指针不太确定,但请看一看是否有对。我相信每个指针都有明显的优点,并在单独的现有问题中回答<代码>配对参与
    make\u shared
    。因为您键入的内容较少,所以效果更好?现在我想知道STL中有多少
    make\u
    函数……与之相关:
    make\u
    智能指针还启用“每个
    新的
    都与
    删除
    配对”通过删除未配对的
    来检查是否正常。不确定如何确保在最后一段中释放内存。你能说得更详细些吗?@LokiAstari这个更好吗?是的。很抱歉,我在逻辑上遇到了问题,整个函数
    make_XX()
    是在第二次函数调用之前完成的。但是,作为一个缺点,如果您保持弱\u ptr,则共享\u ptr中的所有内存将保持活动状态,而不仅仅是ref_count块。(但这在大多数情况下并不重要)