Home > Mobile >  understanding move semantic for a shared_ptr with an rvalue function call
understanding move semantic for a shared_ptr with an rvalue function call

Time:12-22

In the following small program I have two examples of using move with shared_ptr.

The first example behaves as I expected and the ownership of the shared_ptr p is assigned to the new pointer p2. After the assignment p is an invalid pointer.

I would expect the same to happen also in the second example, but it does not. The precise questions are embedded as comments in the source code. What is wrong in my reasoning?

#include <memory>
#include <iostream>
using namespace std;

void foo(shared_ptr<int>&& p)
{
    std::cout << "zoo: " << p.use_count() << "\n";
    // when this function terminates, should the destructor of p
    // decrement the ref counter and destroy the pointed object?
}

void example1()
{
    auto p = make_shared<int>(0);
    std::cout << "count before move: " << p.use_count() << "\n";
    shared_ptr<int> p2(move(p));
    std::cout << "count after move: " << p.use_count() << "\n";  // output 0: ownership transferred to p2
}

void example2()
{
    auto p = make_shared<int>(0);
    std::cout << "count before move: " << p.use_count() << "\n";
    foo(move(p));
    std::cout << "count after move: " << p.use_count() << "\n";
    // output 1: Why is this not zero?
    //Why has ownership not transferred to the argument of the function foo? 
}

int main()
{
    example1();
    example2();
    return 0;
}

CodePudding user response:

Why has ownership not transferred to the argument of the function foo?

Because the parameter type of foo is an rvalue reference of shared_ptr, no new shared_ptr object is created, the p in foo is just a reference to the original p which is not moved to any object.

If you change foo to pass by value, a new shared_ptr object is created, then you will find that p has been moved:

void foo(shared_ptr<int> p)
{
    //...
}
foo(move(p)); // ownership transferred
  • Related