fork download
  1. #include <iostream>
  2. #include <list>
  3. #include <memory>
  4. using namespace std;
  5.  
  6. struct Connection
  7. {
  8. Connection()
  9. {
  10. std::cout << "Connection()" << std::endl;
  11. }
  12.  
  13. ~Connection()
  14. {
  15. std::cout << "~Connection()" << std::endl;
  16. }
  17. };
  18.  
  19. typedef shared_ptr<Connection> ptr_t;
  20.  
  21. class ConnectionReleaser {
  22. list<ptr_t>& whereToReturn;
  23. ptr_t connectionToRelease;
  24. int ver;
  25. static int nextVer;
  26. public:
  27. ConnectionReleaser(list<ptr_t>& lst, const ptr_t& x)
  28. : whereToReturn(lst)
  29. , connectionToRelease(x)
  30. {
  31. ver = nextVer++;
  32. std::cout << "ConnectionReleaser() v." << ver << std::endl;
  33. }
  34.  
  35. ConnectionReleaser(const ConnectionReleaser& rhs)
  36. : whereToReturn(rhs.whereToReturn)
  37. , connectionToRelease(rhs.connectionToRelease)
  38. {
  39. ver = nextVer++;
  40. std::cout << "ConnectionReleaser(rhs v." << rhs.ver << ") v." << ver << std::endl;
  41. }
  42.  
  43. ~ConnectionReleaser()
  44. {
  45. std::cout << "~ConnectionReleaser() v." << ver << std::endl;
  46. }
  47.  
  48. void operator()(Connection*) {
  49. whereToReturn.push_back( connectionToRelease );
  50. // Обратите внимание на следующую строчку
  51. //connectionToRelease.reset();
  52. }
  53. };
  54.  
  55. int ConnectionReleaser::nextVer = 0;
  56.  
  57.  
  58. list<ptr_t> connectionList;
  59.  
  60. ptr_t getConnection() {
  61. std::cout << "enter getConnection()" << std::endl;
  62. ptr_t c( connectionList.back() );
  63. connectionList.pop_back();
  64. ptr_t r( c.get(), ConnectionReleaser( connectionList, c ) );
  65. std::cout << "exit getConnection()" << std::endl;
  66. return r;
  67. }
  68.  
  69. int main() {
  70. connectionList.push_back(make_shared<Connection>());
  71.  
  72. {
  73. weak_ptr<Connection> weak1;
  74. cout << "connectionList.size() = " << connectionList.size() << endl;
  75. auto c = getConnection();
  76. cout << "connectionList.size() = " << connectionList.size() << endl;
  77. weak1 = c;
  78. cout << "weak1.expired() = " << weak1.expired() << endl;
  79. cout << "begin c.reset()" << endl;
  80. c.reset();
  81. cout << "end c.reset()" << endl;
  82. cout << "weak1.expired() = " << weak1.expired() << endl;
  83. cout << "connectionList.size() = " << connectionList.size() << endl;
  84. cout << "deleting weak1" << endl;
  85. }
  86.  
  87. return 0;
  88. }
Success #stdin #stdout 0s 3440KB
stdin
Standard input is empty
stdout
Connection()
connectionList.size() = 1
enter getConnection()
ConnectionReleaser() v.0
ConnectionReleaser(rhs v.0) v.1
ConnectionReleaser(rhs v.1) v.2
ConnectionReleaser(rhs v.2) v.3
ConnectionReleaser(rhs v.3) v.4
ConnectionReleaser(rhs v.4) v.5
~ConnectionReleaser() v.4
~ConnectionReleaser() v.3
~ConnectionReleaser() v.2
~ConnectionReleaser() v.1
~ConnectionReleaser() v.0
exit getConnection()
connectionList.size() = 0
weak1.expired() = 0
begin c.reset()
end c.reset()
weak1.expired() = 1
connectionList.size() = 1
deleting weak1
~ConnectionReleaser() v.5
~Connection()