fork download
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. struct Device;
  6. struct DeviceDependant;
  7.  
  8. struct DeviceDependant {
  9. private:
  10. Device * device_;
  11. public:
  12. DeviceDependant(Device &);
  13. DeviceDependant(DeviceDependant const &);
  14. DeviceDependant(DeviceDependant &&);
  15. ~DeviceDependant();
  16.  
  17. void onDeviceLost(Device * dev) {
  18. std::cout << "DeviceDependant::onDeviceLost() : this = " << (void*)this << ", dev = " << (void*)dev << std::endl;
  19. }
  20.  
  21. void register_self();
  22. void unregister_self();
  23. };
  24.  
  25. struct Device {
  26. private:
  27. std::vector<DeviceDependant *> dependants_;
  28. public:
  29. Device() = default;
  30. ~Device() {
  31. notify_dependants();
  32. }
  33.  
  34. void register_dependant(DeviceDependant * dep) {
  35. std::cout << "Device::register_dependant() : this = " << (void*)this << ", dep = " << (void*)dep << std::endl;
  36. dependants_.push_back(dep);
  37. }
  38.  
  39. void unregister_dependant(DeviceDependant const * dep) {
  40. std::cout << "Device::unregister_dependant() : this = " << (void*)this << ", dep = " << (void*)dep << std::endl;
  41. dependants_.erase(
  42. std::remove_if(
  43. std::begin(dependants_),
  44. std::end(dependants_),
  45. [&](DeviceDependant const * local) { return (local == dep); }
  46. ),
  47. std::end(dependants_)
  48. );
  49. }
  50.  
  51. void notify_dependants() {
  52. for(auto & dep : dependants_) {
  53. dep->onDeviceLost(this);
  54. }
  55. }
  56. };
  57.  
  58. DeviceDependant::DeviceDependant(Device & dev)
  59. : device_(&dev) {
  60. register_self();
  61. }
  62.  
  63. DeviceDependant::DeviceDependant(DeviceDependant const & dep)
  64. : device_(dep.device_) {
  65. register_self();
  66. }
  67.  
  68. DeviceDependant::DeviceDependant(DeviceDependant && dep)
  69. : device_(nullptr) {
  70. dep.unregister_self();
  71. std::swap(device_, dep.device_);
  72. register_self();
  73. }
  74.  
  75. DeviceDependant::~DeviceDependant() {
  76. if(device_) {
  77. device_->unregister_dependant(this);
  78. }
  79. }
  80.  
  81. void DeviceDependant::register_self() {
  82. if(device_) {
  83. device_->register_dependant(this);
  84. }
  85. }
  86.  
  87. void DeviceDependant::unregister_self() {
  88. if(device_) {
  89. device_->unregister_dependant(this);
  90. }
  91. }
  92.  
  93. int main(int argc, char ** argv) {
  94. Device dev;
  95. DeviceDependant dep1(dev);
  96. DeviceDependant dep2(dev);
  97. {
  98. DeviceDependant dep3(dev);
  99. }
  100. DeviceDependant dep4 = std::move(dep2);
  101. dev.notify_dependants();
  102.  
  103. return 0;
  104. }
Success #stdin #stdout 0s 3032KB
stdin
Standard input is empty
stdout
Device::register_dependant() : this = 0xbfa68f04, dep = 0xbfa68ef8
Device::register_dependant() : this = 0xbfa68f04, dep = 0xbfa68efc
Device::register_dependant() : this = 0xbfa68f04, dep = 0xbfa68f00
Device::unregister_dependant() : this = 0xbfa68f04, dep = 0xbfa68f00
Device::unregister_dependant() : this = 0xbfa68f04, dep = 0xbfa68efc
Device::register_dependant() : this = 0xbfa68f04, dep = 0xbfa68f00
DeviceDependant::onDeviceLost() : this = 0xbfa68ef8, dev = 0xbfa68f04
DeviceDependant::onDeviceLost() : this = 0xbfa68f00, dev = 0xbfa68f04
Device::unregister_dependant() : this = 0xbfa68f04, dep = 0xbfa68f00
Device::unregister_dependant() : this = 0xbfa68f04, dep = 0xbfa68ef8