fork(1) download
  1. #include <string>
  2. #include <list>
  3. #include <iostream>
  4. #include <stdexcept>
  5.  
  6. #include <memory>
  7.  
  8. using namespace std;
  9.  
  10. class Connection {
  11. std::string name;
  12. public:
  13. const std::string& getName() const { return name; }
  14.  
  15. explicit Connection(const std::string& n):name(n) {
  16. std::cout << "Connection " << name << std::endl;
  17. }
  18.  
  19. ~Connection() {
  20. name = '~' + name;
  21. std::cout << "~Connection " << name << std::endl;
  22. }
  23. };
  24.  
  25. typedef shared_ptr<Connection> ptr_t;
  26.  
  27. class ConnectionPool {
  28. std::list<ptr_t> connections;
  29.  
  30. // Этот класс предназначен для демонстрации первого варианта создания deleter (get1)
  31. class ConnectionReleaser {
  32. std::list<ptr_t>& whereToReturn;
  33. ptr_t connectionToRelease;
  34. public:
  35. ConnectionReleaser(std::list<ptr_t>& lst, const ptr_t& x):whereToReturn(lst), connectionToRelease(x) {}
  36. ~ConnectionReleaser()
  37. {
  38. cout << "~ConnectionReleaser()" << endl;
  39. cout << connectionToRelease.get() << endl;
  40. if (0 == connectionToRelease.get())
  41. {
  42. cout << "NULL" << endl;
  43. }
  44. else
  45. {
  46. cout << connectionToRelease->getName() << endl;
  47. }
  48. }
  49.  
  50. void operator()(Connection*) {
  51. whereToReturn.push_back( connectionToRelease );
  52. std::cout << "get1: Returned connection " << connectionToRelease->getName() << " to the list" << std::endl;
  53.  
  54. // Закомментируйте след. строку и обратите внимание на разницу в выходной печати
  55. //connectionToRelease.reset();
  56. }
  57. };
  58.  
  59. // Эта функция предназначена для демонстрации второго варианта создания deleter (get2)
  60. static void releaseConnection(std::list<ptr_t>& whereToReturn, ptr_t& connectionToRelease) {
  61. whereToReturn.push_back( connectionToRelease );
  62. std::cout << "get2: Returned connection " << connectionToRelease->getName() << " to the list" << std::endl;
  63.  
  64. // Закомментируйте следующую строку и обратите внимание на разницу в выходной печати
  65. connectionToRelease.reset();
  66. }
  67.  
  68. ptr_t popConnection() {
  69. if( connections.empty() ) throw std::runtime_error("No connections left");
  70. ptr_t w( connections.back() );
  71. connections.pop_back();
  72. return w;
  73. }
  74. public:
  75. ptr_t get1() {
  76. ptr_t w = popConnection();
  77. std::cout << "get1: Taken connection " << w->getName() << " from list" << std::endl;
  78. ptr_t r( w.get(), ConnectionReleaser( connections, w ) );
  79. return r;
  80. }
  81.  
  82. ptr_t get2() {
  83. ptr_t w = popConnection();
  84. std::cout << "get2: Taken connection " << w->getName() << " from list" << std::endl;
  85. ptr_t r( w.get(), bind(&releaseConnection, ref(connections), w ));
  86. return r;
  87. }
  88.  
  89. void add(const std::string& name) {
  90. connections.push_back( ptr_t(new Connection(name)) );
  91. }
  92.  
  93. ConnectionPool() {
  94. std::cout << "ConnectionPool" << std::endl;
  95. }
  96.  
  97. ~ConnectionPool() {
  98. std::cout << "~ConnectionPool" << std::endl;
  99. }
  100. };
  101.  
  102. int main() {
  103. weak_ptr<Connection> weak1;
  104. weak_ptr<Connection> weak2;
  105. {
  106. ConnectionPool cp;
  107. cp.add("One");
  108. cp.add("Two");
  109.  
  110. ptr_t p1 = cp.get1();
  111. weak1 = p1;
  112. //ptr_t p2 = cp.get2();
  113. //weak2 = p2;
  114. }
  115. std::cout << "weak1.expired()" << weak1.expired() << endl;
  116. std::cout << "Here the ConnectionPool is out of scope, but weak_ptrs are not" << std::endl;
  117. return 0;
  118. }
Success #stdin #stdout 0s 3444KB
stdin
Standard input is empty
stdout
ConnectionPool
Connection One
Connection Two
get1: Taken connection Two from list
~ConnectionReleaser()
0x8fcd078
Two
~ConnectionReleaser()
0x8fcd078
Two
~ConnectionReleaser()
0x8fcd078
Two
~ConnectionReleaser()
0x8fcd078
Two
~ConnectionReleaser()
0x8fcd078
Two
get1: Returned connection Two to the list
~ConnectionPool
~Connection ~One
weak1.expired()1
Here the ConnectionPool is out of scope, but weak_ptrs are not
~ConnectionReleaser()
0x8fcd078
Two
~Connection ~Two