#include /* RefCounter. Analogous to std::shared_ptr. */ template class Rc { T *data; std::size_t *refs; public: explicit Rc(const T &); // Copy ctor explicit Rc(T &&); // Move ctor Rc(const Rc &); // Copy ctor Rc(Rc &&); // Move ctor void operator=(const Rc &); // Copy assign void operator=(Rc &&); // Move assign ~Rc(); const T &borrow() noexcept; T &borrow_mut() noexcept; }; template Rc::Rc(const T &data) : Rc(std::move(data)) {} template Rc::Rc(T &&data) : data(new T(std::move(data))) , refs(new std::size_t(1)) {} template Rc::Rc(const Rc &other) : data(other.data) , refs(other.refs) { refs++; } template Rc::Rc(Rc &&other) : data(other.data) , refs(other.refs) { other.refs = nullptr; other.data = nullptr; } template void Rc::operator=(const Rc &other) {} template void Rc::operator=(Rc &&other) {} template Rc::~Rc() { if (--refs == 0) delete data; } template const T &Rc::borrow() noexcept { return *data; } template T &Rc::borrow_mut() noexcept { return *data; } int main() { std::cout << "Template" << std::endl; Rc a = Rc(10); auto b = Rc(10); b.borrow_mut()++; std::cout << a.borrow() << std::endl; std::cout << b.borrow() << std::endl; a = b; }