#include using namespace std; class Table {}; class Name { public: Name(const char *s) {} }; class Node { unique_ptr table; unique_ptr name; public: Node(const char *n = "") : table(new Table()), name(new Name(n)) {} // ~Node() { delete table; delete name; } // Node( const Node & other ) = delete; // Node & operator=( const Node & other ) = delete; /* * Thanks to the overloading of the pointer operators, there is no need * to change anything else in the code that implements Node's methods - we can * use table/name as normal pointers. * * Because unique_ptr *deletes* its copy constructor and (copy) assignment * operator we will not need to provide these if we do not want our objects to * be copied - the compiler will delete our copy constructor and (copy) * assignment operator as well. * * However, if we want to allow copying and assignment, then we need to provide * them ourselves, as below. */ // Deep copy, not copying just the unique_ptr's! Node( const Node & other ) : table(new Table( * (other.table) )), name (new Name( * (other.name) )) {} /* Node &operator= ( const Node & other ) { if (&other != this) { table.reset(new Table( * (other.table) )); name.reset( new Name( * (other.name) )); } return *this; } */ // Why is this a good implementation too? Node &operator= ( Node other ) { std::swap(table, other.table); std::swap(name, other.name); return *this; } // ... }; int main() { Node n1("Hi"); Node n2( n1 ); // copy constructor Node n3("Bye"); n1 = n3; // (copy) assignment operator return 0; }