#include <algorithm>
#include <iostream>
#include <vector>
struct Device;
struct DeviceDependant;
struct DeviceDependant {
private:
Device * device_;
public:
DeviceDependant(Device &);
DeviceDependant(DeviceDependant const &);
DeviceDependant(DeviceDependant &&);
~DeviceDependant();
void onDeviceLost(Device * dev) {
std::cout << "DeviceDependant::onDeviceLost() : this = " << (void*)this << ", dev = " << (void*)dev << std::endl;
}
void register_self();
void unregister_self();
};
struct Device {
private:
std::vector<DeviceDependant *> dependants_;
public:
Device() = default;
~Device() {
notify_dependants();
}
void register_dependant(DeviceDependant * dep) {
std::cout << "Device::register_dependant() : this = " << (void*)this << ", dep = " << (void*)dep << std::endl;
dependants_.push_back(dep);
}
void unregister_dependant(DeviceDependant const * dep) {
std::cout << "Device::unregister_dependant() : this = " << (void*)this << ", dep = " << (void*)dep << std::endl;
dependants_.erase(
std::remove_if(
std::begin(dependants_),
std::end(dependants_),
[&](DeviceDependant const * local) { return (local == dep); }
),
std::end(dependants_)
);
}
void notify_dependants() {
for(auto & dep : dependants_) {
dep->onDeviceLost(this);
}
}
};
DeviceDependant::DeviceDependant(Device & dev)
: device_(&dev) {
register_self();
}
DeviceDependant::DeviceDependant(DeviceDependant const & dep)
: device_(dep.device_) {
register_self();
}
DeviceDependant::DeviceDependant(DeviceDependant && dep)
: device_(nullptr) {
dep.unregister_self();
std::swap(device_, dep.device_);
register_self();
}
DeviceDependant::~DeviceDependant() {
if(device_) {
device_->unregister_dependant(this);
}
}
void DeviceDependant::register_self() {
if(device_) {
device_->register_dependant(this);
}
}
void DeviceDependant::unregister_self() {
if(device_) {
device_->unregister_dependant(this);
}
}
int main(int argc, char ** argv) {
Device dev;
DeviceDependant dep1(dev);
DeviceDependant dep2(dev);
{
DeviceDependant dep3(dev);
}
DeviceDependant dep4 = std::move(dep2);
dev.notify_dependants();
return 0;
}