#include <memory>
class interface_d
{
public:
virtual ~interface_d() {}
virtual interface_d* clone() const = 0;
};
class d1
: public interface_d
{
public:
d1() : interface_d(), m_x(new int) {}
d1(const d1 &rhs) : interface_d(), m_x(new int(*rhs.m_x)) {}
virtual ~d1()
{
delete m_x;
}
virtual interface_d* clone() const
{
return new d1(*this);
}
private:
int *m_x;
};
class base
{
public:
base(std::unique_ptr<interface_d> impl) : m_impl(std::move(impl)) {}
base(const base &rhs) : m_impl(rhs.m_impl->clone()) {}
base& operator=(const base &rhs)
{
if (this != &rhs)
{
std::unique_ptr<interface_d> tmp(rhs.m_impl->clone());
std::swap(m_impl, tmp);
}
return *this;
}
~base()
{
// ... do something before clear impl
m_impl.reset();
// ... do something after clear impl
}
private:
std::unique_ptr<interface_d> m_impl;
};
int main() {
base x(std::unique_ptr<d1>(new d1));
base y(x);
return 0;
}
I2luY2x1ZGUgPG1lbW9yeT4KCmNsYXNzIGludGVyZmFjZV9kCnsKcHVibGljOgoJdmlydHVhbCB+aW50ZXJmYWNlX2QoKSB7fQoJdmlydHVhbCBpbnRlcmZhY2VfZCogY2xvbmUoKSBjb25zdCA9IDA7Cgp9OwoKY2xhc3MgZDEKCTogcHVibGljIGludGVyZmFjZV9kCnsKcHVibGljOgoJZDEoKSA6IGludGVyZmFjZV9kKCksIG1feChuZXcgaW50KSB7fQoJZDEoY29uc3QgZDEgJnJocykgOiBpbnRlcmZhY2VfZCgpLCBtX3gobmV3IGludCgqcmhzLm1feCkpIHt9Cgl2aXJ0dWFsIH5kMSgpCgl7CgkJZGVsZXRlIG1feDsKCX0KCgl2aXJ0dWFsIGludGVyZmFjZV9kKiBjbG9uZSgpIGNvbnN0Cgl7CgkJcmV0dXJuIG5ldyBkMSgqdGhpcyk7Cgl9Cgpwcml2YXRlOgoJaW50ICptX3g7Cn07CgpjbGFzcyBiYXNlCnsKcHVibGljOgoJYmFzZShzdGQ6OnVuaXF1ZV9wdHI8aW50ZXJmYWNlX2Q+IGltcGwpIDogbV9pbXBsKHN0ZDo6bW92ZShpbXBsKSkge30KCWJhc2UoY29uc3QgYmFzZSAmcmhzKSA6IG1faW1wbChyaHMubV9pbXBsLT5jbG9uZSgpKSB7fQoJYmFzZSYgb3BlcmF0b3I9KGNvbnN0IGJhc2UgJnJocykKCXsKCQlpZiAodGhpcyAhPSAmcmhzKQoJCXsKCQkJc3RkOjp1bmlxdWVfcHRyPGludGVyZmFjZV9kPiB0bXAocmhzLm1faW1wbC0+Y2xvbmUoKSk7CgkJCXN0ZDo6c3dhcChtX2ltcGwsIHRtcCk7CgkJfQoJCXJldHVybiAqdGhpczsKCX0KCX5iYXNlKCkKCXsKCQkvLyAuLi4gZG8gc29tZXRoaW5nIGJlZm9yZSBjbGVhciBpbXBsCgkJbV9pbXBsLnJlc2V0KCk7CgkJLy8gLi4uIGRvIHNvbWV0aGluZyBhZnRlciBjbGVhciBpbXBsCgl9Cgpwcml2YXRlOgoJc3RkOjp1bmlxdWVfcHRyPGludGVyZmFjZV9kPiBtX2ltcGw7Cn07CgppbnQgbWFpbigpIHsKCgliYXNlIHgoc3RkOjp1bmlxdWVfcHRyPGQxPihuZXcgZDEpKTsKCWJhc2UgeSh4KTsKCQoJcmV0dXJuIDA7Cn0=