/*****************************************************************************
 * This class definition of 'Pair' corrects the problems in the bad default
 * example. 
 *
 * The copy constructor allocates new memory to the new 'Pair'
 * and fills it with copies of the values in the old 'Pair'. 
 *
 * The assignment operator copies the contents of the memory associated with 
 * the right hand 'Pair' into the memory associated with the left hand 'Pair'.
 * (In many classes using dynamically allocated memory, one must deallocate
 * the memory of the left hand object, then allocate memory to hold the 
 * values copied from the right hand object.)
 *
 * The destructor deallocates the memory allocated by the constructors. 
 * 
 * **************************************************************************/
#include<iostream>
#include<iomanip>

using std::cin; using std::cout;
using std::endl; using std::ostream;
using std::istream;
class Pair
{
	double* p;
	friend ostream& operator<<(ostream&, Pair);
	public:
	Pair(const Pair & a) //deep copy constructor
	{
		p=new double[2];
		p[0]=a.p[0];
		p[1]=a.p[1];
	}
	~Pair()// the destructor
	{
		delete[] p;
	}
	const Pair& operator=(const Pair& rhs)// the assignment operator
	{
		if(&rhs!= this) /* 'this' is the address of the calling object.
				   Doing nothing if 'rhs' is already the 
				  calling object avoids trouble and saves time.
				 */ 
		{
			p[0]=rhs.p[0];
			p[1]=rhs.p[1];
		}
		return *this;
	}
			
	Pair()
	{
		p=new double[2];
	}
	Pair( double x, double y)
	{
		p= new double[2];
		p[0]=x;
		p[1]=y;
	}
	void set_x(double z)
	{
		p[0]=z;
	}
	double get_x() const
	{
		return p[0];
	}
	void set_y(double z) const
	{
		p[1]=z;
	}
	double get_y()
	{
		return p[1];
	}
};
istream& operator>> (istream& is, Pair& pair)
{
	double temp;
	is>>temp;
	pair.set_x(temp);
	is>>temp;
	pair.set_y(temp);
	return is;
}
int main()
{
	Pair ones(1.0,1.1);
	cout<<"ones: "<<ones.get_x()<<", "<<ones.get_y()<<endl;
	Pair others;
	cout<<"others: "<<others.get_x()<<", "<<others.get_y()<<endl;
	others.set_x(3.3);
	others.set_y(4.5);
	cout<<"others: "<<others.get_x()<<", "<<others.get_y()<<endl;
	others=ones;// Use the assignment operator written explicitly. 
	cout<<"others: "<<others.get_x()<<", "<<others.get_y()<<endl;
	others.set_x(6.02);
	others.set_y(300000);
	cout<<"others: "<<others.get_x()<<", "<<others.get_y()<<endl;
	cout<<"ones: "<<ones.get_x()<<", "<<ones.get_y()<<endl;
	Pair more(ones);//Use the copy constructor written explicitly.
	more.set_x(666);
	cout<<"more: "<<more.get_x()<<", "<<more.get_y()<<endl;
	cout<<"ones: "<<ones;
	cout<<"\nPlease enter two doubles for x and y: ";
	cin>>more;
	cout<<"\nThat's "<<more<<endl;
	


	return 0;
}
ostream& operator<<(ostream& os, Pair pair)
{
	os<<"("<<pair.p[0]<<", "<<pair.p[1]<<")";
	return os;
}	
		
