/* Lecture code 16.3
 *
 * Demonstrating how to use the Uncopyable class to disallow copying.
 */

#include <iostream>
#include <string>
using namespace std;

/* Uncopyable is a class that cannot be instantiated directly or copied.
 * See below for details.
 */
class Uncopyable
{
protected:
	/* Because the constructor and destructor for Uncopyable are marked protected,
	 * we cannot directly instantiate an Uncopyable class because doing so would
	 * access a protected function.  Thus code like
	 *
	 * Uncopyable uc;
	 * Uncopyable* pUc = new Uncopyable;
	 *
	 * Will not compile.
	 */
	Uncopyable() {}
	~Uncopyable() {}
private:
	/* Marking the copy constructor and assignment operator private disallows
	 * copying of Uncopyable objects since doing so would access private fields.
	 */
	Uncopyable(const Uncopyable& other);
	Uncopyable& operator= (const Uncopyable& other);
};

/* Demonstrating how a class inheriting from Uncopyable is uncopyable.  Because
 * MyClass does not define its own copy constructor or assignment operator, C++
 * will try to automatically provide it with one that does a copy of the data
 * members and base classes.  However, the base class has its copy constructor
 * and assignment operator marked private, so C++'s automatically-generated copy
 * functions are ill-defined and cause an error if used.
 *
 * The use of private inheritance here is a bit tricky.  Private inheritance
 * indicates that MyClass should absorb all of the functionality of Uncopyable,
 * but is _not_ considered a subtype of Uncopyable.  Thus the following code
 * will not compile:
 *
 * Uncopyable* u = new MyClass; // Error!
 *
 * Private inheritance is used only rarely in practice, so don't worry too much
 * if you're tripped up by exactly what's going on here.
 */
class MyClass: private Uncopyable
{
};

int main()
{
	MyClass one, two;
	MyClass three = one; // Error!
	two = one; // Error!
	return 0;
}