fork download
  1. #include <iostream>
  2. #include <memory>
  3. #include <vector>
  4.  
  5. struct A {
  6. std::string s = "foo";
  7. std::weak_ptr<A> h;
  8. std::shared_ptr<A> && getR() {
  9. return std::move(h.lock());
  10. }
  11. std::shared_ptr<A> getL() {
  12. return h.lock();
  13. }
  14. };
  15.  
  16. std::vector< std::shared_ptr<A> > storage;
  17. std::vector< std::weak_ptr<A> > accountant;
  18.  
  19. void store(std::shared_ptr<A> && rr) {
  20. std::cout << "store '" << rr->s << "' uses: " << rr.use_count() << std::endl;
  21. storage.push_back(std::move(rr));
  22. }
  23.  
  24. int main() {
  25. // create keeper of A
  26. auto keeper = std::make_shared<A>();
  27. keeper->s = "bar";
  28. // store weak_ptr-type handle with accountant
  29. accountant.push_back(keeper);
  30. // backref handle to A
  31. keeper->h = accountant[0];
  32.  
  33. std::cout << "# case 0: manual 'move'" << std::endl;
  34. {
  35. store(std::move(accountant[0].lock()));
  36.  
  37. std::cout << "uses: " << keeper.use_count() << std::endl;
  38. }
  39. storage.clear();
  40.  
  41. std::cout << "# case 1: manual 'move' from internal" << std::endl;
  42. {
  43. store(std::move(keeper->h.lock()));
  44.  
  45. std::cout << "uses: " << keeper.use_count() << std::endl;
  46. }
  47. storage.clear();
  48.  
  49. std::cout << "# case 2: return copy from func" << std::endl;
  50. {
  51. store(keeper->getL());
  52.  
  53. std::cout << "uses: " << keeper.use_count() << std::endl;
  54. }
  55. storage.clear();
  56. // all is well up to here.
  57.  
  58. std::cout << "# case 3: return rref from func" << std::endl;
  59. {
  60. store(keeper->getR());
  61.  
  62. std::cout << "uses: " << keeper.use_count() << std::endl;
  63. std::cout << "storage[0]: " << storage[0].get() << " uses: " << storage[0].use_count() << " " << &storage[0] << std::endl;
  64. std::cout << "keeper: " << keeper.get() << " uses: " << keeper.use_count() << " " << &keeper << std::endl;
  65. }
  66. storage.clear();
  67.  
  68. std::cout << "# after" << std::endl;
  69. std::cout << "uses: " << keeper.use_count() << std::endl;
  70. // all the A is gone!!!!
  71. return 0;
  72. }
Success #stdin #stdout 0s 15248KB
stdin
Standard input is empty
stdout
# case 0: manual 'move'
store 'bar' uses: 2
uses: 2
# case 1: manual 'move' from internal
store 'bar' uses: 2
uses: 2
# case 2: return copy from func
store 'bar' uses: 2
uses: 2
# case 3: return rref from func
store 'bar' uses: 1
uses: 1
storage[0]: 0x2b49f7a0fc30 uses: 1 0x2b49f7a10ca0
keeper: 0x2b49f7a0fc30 uses: 1 0x7ffd3683be20
# after
uses: 0