理解std::move和std::unique_ptr在C++中的所有权转移。

huangapple go评论77阅读模式
英文:

Understanding std::move and Ownership Transfer with std::unique_ptr in C++

问题

以下是您要翻译的代码部分:

我已经编写了两组函数,F1/test1  F2/test2,并且我正在尝试理解在这些函数中使用 std::move  std::unique_ptr 转移所有权的行为差异。以下是代码:

    void F1(std::unique_ptr<Dog>&& uPtr)
    {
        std::cout << "F1 \n";
    }
    
    void test1()
    {
        std::unique_ptr<Dog> pD(new Dog("Gunner"));
        F1(std::move(pD));
        if (pD == nullptr)
        {
            std::cout << "Null\n";
        }
        std::cout << "Test \n";
    }
    
    void F2(std::unique_ptr<Dog> uPtr)
    {
        std::cout << "F2 \n";
    }
    
    void test2()
    {
        std::unique_ptr<Dog> pD(new Dog("Smokey"));
        F2(std::move(pD));
        if (pD == nullptr)
        {
            std::cout << "Null\n";
        }
        std::cout << "Test \n";
    }

请注意,我只翻译了代码部分,没有提供问题的答案或其他内容。

英文:

I have written two sets of functions, F1/test1 and F2/test2 and I'm trying to understand the differences in the behavior of std::move and the transfer of ownership with std::unique_ptr in these functions. Here is the code:

void F1(std::unique_ptr&lt;Dog&gt;&amp;&amp; uPtr)
{
    std::cout &lt;&lt; &quot;F1 \n&quot;;
}

void test1()
{
    std::unique_ptr&lt;Dog&gt; pD(new Dog(&quot;Gunner&quot;));
    F1(std::move(pD));
    if (pD == nullptr)
    {
        std::cout &lt;&lt; &quot;Null\n&quot;;
    }
    std::cout &lt;&lt; &quot;Test \n&quot;;
}

void F2(std::unique_ptr&lt;Dog&gt; uPtr)
{
    std::cout &lt;&lt; &quot;F2 \n&quot;;
}

void test2()
{
    std::unique_ptr&lt;Dog&gt; pD(new Dog(&quot;Smokey&quot;));
    F2(std::move(pD));
    if (pD == nullptr)
    {
        std::cout &lt;&lt; &quot;Null\n&quot;;
    }
    std::cout &lt;&lt; &quot;Test \n&quot;;
}

In test1, F1 is called with std::move(pD) as the argument, where uPtr is an rvalue reference to std::unique_ptr. After the call to F1, I checked if pD is null. I was expecting that pD would be null because std::move(pD) was used to pass it to F1, but it's not null. Why is this the case?

In test2, F2 is called with std::move(pD) as the argument, where uPtr is a by-value parameter of type std::unique_ptr. After the call to F2, I checked if pD is null. In this case, pD is null. This is as I expected because std::move(pD) was used to pass it to F2, but why is this behavior different from test1?

Any help would be appreciated!

答案1

得分: 2

对象在调用移动构造函数或移动赋值操作符之前不会被移动。std::move只是将左值转换为右值的一个强制类型转换操作符,在这一点上实际上没有移动任何数据。对于std::move,一个更好的名称应该是std::cast_to_rvalue,但那会有点冗长。

对于F1,指针通过右值引用传递,所以函数仍然使用来自调用者的实例。由于在函数中未修改uPtr,原始指针仍然有效。

对于F2,指针通过值传递,因此在进入函数之前必须调用移动构造函数来创建新对象。尽管在函数中未修改指针,但移动操作已经发生,因此调用者的实例受到影响。

英文:

An object is not moved until a call to the move constructor or the move assignment operator is done. std::move is only a cast operator from an lvalue to an rvalue, no data is actually moved at that point. A better name for std::move would be std::cast_to_rvalue but that would be a bit verbose.

For F1, the pointer is passed by rvalue reference so the function is still using the instance from the caller. Since uPtr is untouched in the function, the original pointer will still be valid.

For F2, the pointer is passed by value so the move constructor will have to be called before entering the function to create the new object. Even though the pointer is untouched in the function, the move operation has already taken place so the instance of the caller is affected.

答案2

得分: 1

这只是将一个r值引用进行转换

F1(std::move(pD));

void F1(std::unique_ptr&lt;Dog&gt;&amp;&amp; uPtr)
{
    std::cout &lt;&lt; &quot;F1 \n&quot;;
}

实际上对uPtr没有做任何操作。它可以假设std_ptr即将被销毁并将其保留在一个不确定但有效的状态。您的代码没有这样做。

F2 使用了移动构造函数,详见这里的构造函数 5。

英文:

This is just a conversion to an r-value reference

F1(std::move(pD));

The

void F1(std::unique_ptr&lt;Dog&gt;&amp;&amp; uPtr)
{
    std::cout &lt;&lt; &quot;F1 \n&quot;;
}

Doesn't actually do anything to uPtr. It can assume the std_ptr is about to be destroyed and leave it in a indeterminate but valid state. Yours does not do that.

F2 is using the move constructor, https://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr look at constructor 5.

huangapple
  • 本文由 发表于 2023年6月26日 04:19:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552262.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定