通过右值函数调用理解 shared_ptr 的移动语义
understanding move semantic for a shared_ptr with an rvalue function call
在下面的小程序中,我有两个使用 move
和 shared_ptr
的例子。
第一个示例的行为符合我的预期,shared_ptr
p
的所有权已分配给新指针 p2
。赋值后p
是无效指针
我希望在第二个示例中也会发生同样的情况,但事实并非如此。精确的问题作为注释嵌入在源代码中。我的推理有什么问题?
#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;
}
Why has ownership not transferred to the argument of the function foo?
因为foo
的参数类型是shared_ptr
的右值引用,没有创建新的shared_ptr
对象,[= foo
中的 14=] 只是对原始 p
的 引用 , 未 移动到任何对象。
如果你把foo
改成传值,就会创建一个新的shared_ptr
对象,那么你会发现p
有已移动:
void foo(shared_ptr<int> p)
{
//...
}
foo(move(p)); // ownership transferred
在下面的小程序中,我有两个使用 move
和 shared_ptr
的例子。
第一个示例的行为符合我的预期,shared_ptr
p
的所有权已分配给新指针 p2
。赋值后p
是无效指针
我希望在第二个示例中也会发生同样的情况,但事实并非如此。精确的问题作为注释嵌入在源代码中。我的推理有什么问题?
#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;
}
Why has ownership not transferred to the argument of the function foo?
因为foo
的参数类型是shared_ptr
的右值引用,没有创建新的shared_ptr
对象,[= foo
中的 14=] 只是对原始 p
的 引用 , 未 移动到任何对象。
如果你把foo
改成传值,就会创建一个新的shared_ptr
对象,那么你会发现p
有已移动:
void foo(shared_ptr<int> p)
{
//...
}
foo(move(p)); // ownership transferred