std::move
当我们调用 std::move(something) 的时候,此时还并没有发生所有权的转义,我们只是给 something 上打了一个标签,告诉 C++ 现在这个 something 可以被移动.当我们执行 another = std::move(something) 这个赋值的时候,C++ 调用 another 的移动构造函数,在 another 的移动构造函数里,我们把 something 的底层指针赋值给 another,并且将 something 清空,整个移动的过程其实是在移动构造函数里完成的,而非 std::move() 里.
可以看综合示例中 std::ignore = std::move(ptrs[0]) 这一行.由于左边是 std::ignore,其移动构造函数不会做任何事,所以 ptrs[0] 并没有清空,所以 observer 的 .use_count() 依然为 2.
综合示例
一个很好的例子,综合运用了 shared_ptr, weak_ptr 和引用计数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include "../exercise.h" #include <memory>
int main(int argc, char **argv) { auto shared = std::make_shared<int>(10); std::shared_ptr<int> ptrs[]{shared, shared, shared};
std::weak_ptr<int> observer = shared; ASSERT(observer.use_count() == 4, "");
ptrs[0].reset(); ASSERT(observer.use_count() == 3, "");
ptrs[1] = nullptr; ASSERT(observer.use_count() == 2, "");
ptrs[2] = std::make_shared<int>(*shared); ASSERT(observer.use_count() == 1, "");
ptrs[0] = shared; ptrs[1] = shared; ptrs[2] = std::move(shared); ASSERT(observer.use_count() == 3, "");
std::ignore = std::move(ptrs[0]); ptrs[1] = std::move(ptrs[1]); ptrs[1] = std::move(ptrs[2]); ASSERT(observer.use_count() == 2, "");
shared = observer.lock(); ASSERT(observer.use_count() == 3, "");
shared = nullptr; for (auto &ptr : ptrs) ptr = nullptr; ASSERT(observer.use_count() == 0, "");
shared = observer.lock(); ASSERT(observer.use_count() == 0, "");
return 0; }
|