Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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::move和std::shared\u ptr_C++_C++11_Shared Ptr_Move Semantics - Fatal编程技术网

C++ 使用std::move和std::shared\u ptr

C++ 使用std::move和std::shared\u ptr,c++,c++11,shared-ptr,move-semantics,C++,C++11,Shared Ptr,Move Semantics,我有一个定义如下的函数: void foo(std::shared_ptr<X> x) { ... }; foo(std::move(sourcePtr)); 然后我可以按如下方式调用foo: void foo(std::shared_ptr<X> x) { ... }; foo(std::move(sourcePtr)); 或 我知道如果我使用第一个选项,sourcePtr将变为空。它是否也阻止了引用计数的增加 如果这不重要,我应该选择哪个选项?在做出这样的决定

我有一个定义如下的函数:

void foo(std::shared_ptr<X> x) { ... };
foo(std::move(sourcePtr));
然后我可以按如下方式调用
foo

void foo(std::shared_ptr<X> x) { ... };
foo(std::move(sourcePtr));

我知道如果我使用第一个选项,
sourcePtr
将变为空。它是否也阻止了引用计数的增加


如果这不重要,我应该选择哪个选项?在做出这样的决定时,我是否应该考虑其他事项?

是的,如果将共享指针移动到函数中,则:

  • 原始
    sourcePtr
    将变为空,并且

  • 引用计数未被修改

  • 如果您知道在函数调用后不再需要
    sourcePtr
    的值,则将其移动到函数中是一个轻微的优化,因为它可以节省原子增量(以及以后
    sourcePtr
    超出范围时的递减)

    但是,请注意,标识符
    sourcePtr
    对于作用域的其余部分仍然有效,只是它包含一个空指针。这意味着如果您在移动之后使用它,编译器不会抱怨,但是如果您忘记了它是从哪里移动的,那么很可能会取消对null的引用。我倾向于经常使用这种“优化”
    move
    ,我也曾被它咬过几次:更多的功能被添加到函数中,如果你忘记撤消
    move
    ,你会得到一个很好的崩溃

    因此,当您不再需要移动时,这是一个轻微的优化,再加上轻微的维护负担。这取决于你权衡哪一个在你的情况下更重要

    以上假设在声明和最后调用
    foo
    之间存在实际使用
    sourcePtr
    的代码(感谢@WhozCraig指出)。如果没有,最好在调用站点创建指针:

    foo(std::make_shared<X>(...));
    
    foo(std::make_shared(…);
    

    这样,您可以保存相同数量的原子操作,并且不会有潜在危险的空共享指针。

    简言之,引用计数器不会增加,这是正确的。但是,我没有看到它的实际用途,除非您想强制将传递的指针清空,在这种情况下,您可以使用
    std::unique_ptr
    。您不应该将新的智能指针视为指针,而应该从资源所有权的角度来看待它们。一个资源只能由一个实体(
    std::unique\u ptr
    )或多个实体(
    std::shared\u ptr
    )拥有。这是一个非常类似的问题,尽管我不确定是否完全重复:。这个问题是关于将参数传递给函数的-以这种方式不同…@JoachimPileborg这是一些测试代码的简化示例,它并没有讲述整个故事,但允许我将问题专门集中在我想知道的内容上
    Foo
    需要在我的应用程序中使用
    shared\u ptr
    ,但调用后测试代码不需要
    sourcePtr
    。我认为这没有意义。这就是为什么引入了
    shared\u ptr
    ——这不仅是因为安全性(在避免内存泄漏方面),还因为复制对象的成本很高,可以(几乎)免费安全地共享。优化单个原子操作听起来像是浪费时间。为了我自己的澄清,如果创建和调用确实像示例一样简单(可能不是),那么就不会
    foo(std::make_shared(…)在不放弃的情况下完成同样的事情(正如你所指出的,潜在的风险)
    std::shared\u ptr
    shell?当然,如果在这两者(分配和调用)之间存在中间代码
    sourcePtr->member()
    code,则这不是一个选项。但是如果没有呢?虽然我同意其他人的观点,这种优化违背了共享的目的,但这是我发现的第一篇讨论移动和复制指针的可维护性问题的文章(+1)。在许多情况下,由于不需要全局变量的原因,您不希望到处引用同一资源。如果您有动态绑定,您仍然需要指针,特别是
    unique\u ptr
    。然后您必须使用
    move
    (更多代码),但您可以更好地控制资源,并获得轻微的性能提升。