Working with Classes

Operator Overloading



// vector0.h -- vector class before operator overloading

#ifndef _VECTOR0_H_
#define _VECTOR0_H_
class Vector
{
private:
	double x;				// horizontal value
	double y;				// vertical value
	double mag;				// length of vector
	double ang;				// direction of vector
	void set_mag(void);
	void set_ang(void);
public:
	Vector(void);
	Vector(double h, double v);		// set x, y values
	~Vector(void);
	void set_by_polar(double m, double a);
	double xval() const {return x;}	// report x value
	double yval() const {return y;}	// report y value
	double magval() const {return mag;}	// report magnitude
	double angval() const {return ang;}	// report angle
	void show_polar(void) const;	// show polar values
	void show_vector(void) const ;	// show rectangular values
};
#endif


// vector1.h -- Vector class, introduce operator overloading

#ifndef _VECTOR1_H_
#define _VECTOR1_H_
class Vector
{
private:
	double x;				// horizontal value
	double y;				// vertical value
	double mag;				// length of vector
	double ang;				// direction of vector
	void set_mag(void);
	void set_ang(void);
public:
	Vector(void);
	Vector(double h, double v);
    ~Vector(void);
	double xval() const {return x;}	// report x value
	double yval() const {return y;}	// report y value
	double magval() const {return mag;}	// report magnitude
	double angval() const {return ang;}	// report angle
	void set_by_polar(double m, double a);
	void show_polar(void); 		// show polar values
	void show_vector(void);		// show rectilinear values
// operator overloading
	Vector operator+(const Vector & b) const;
	Vector operator-(const Vector & b) const;
	Vector operator-() const;
	Vector operator*(double n) const;
// friend function
	friend Vector operator*(double n, const Vector & a);
};
#endif


// vector1.cpp -- methods for Vector class

#include <iostream.h>
#include <math.h>
#include "vector1.h"
const double Rad_to_deg = 57.2957795130823;

// private methods
// calculates magnitude from x and y
void Vector::set_mag(void)
{
	mag = sqrt(x * x + y * y);
}

// calculates angle from x and y
void Vector::set_ang(void)
{
	ang = atan2(y, x);
}

// public methods
Vector::Vector(void)	// default constructor
{
	x = y = mag = ang = 0.0;
}

// constructs a Vector from rectangular coordinates
Vector::Vector(double h, double v)
{
	x = h;
	y = v;
	set_mag();
	set_ang();
}

Vector::~Vector(void)	// destructor
{
}

// sets Vector members from polar coordinates
void Vector::set_by_polar(double m, double a)
{
	mag = m;
	ang = a / Rad_to_deg;
	x = m * cos (a);
	y = m * sin (a);
}

// shows magnitude and direction of vector
void Vector::show_polar(void)
{
	cout << "(" << mag << ", ";
	cout << ang * Rad_to_deg << ")\n";
}

// shows x and y components of vector
void Vector::show_vector(void)
{
	cout << "(" << x << ", " << y << ")\n";
}

// operator overloading
// add two Vectors
Vector Vector::operator+(const Vector & b) const
{
	double sx, sy;
	sx = x + b.x;
	sy = y + b.y;
	Vector sum = Vector(sx, sy);
	return sum;
}

// subtract Vector b from a
Vector Vector::operator-(const Vector & b) const
{
	double dx, dy;
	dx = x - b.x;
	dy = y - b.y;
	Vector diff = Vector(dx, dy);
	return diff;
}

// reverse sign of Vector
Vector Vector::operator-() const
{
	double nx, ny;
	nx = -x;
	ny = -y;
	Vector neg = Vector(nx, ny);
	return neg;
}

// multiple vector by n
Vector Vector::operator*(double n) const
{
	double mx, my;
	mx = n * x;
	my = n * y;
	Vector mult = Vector(mx, my);
	return mult;
}

// friend method
// multiply n by Vector a
Vector operator*(double n, const Vector & a)
{
	return a * n;
}



// use_vect.cpp -- use the Vector class

// compile with vector1.cpp
#include <iostream.h>
#include "vector1.h"
int main(void)
{
	Vector first_move(120, 50);
	Vector second_move(50, 120);
	Vector result;
	cout.precision(3);			// format output
	cout.setf(ios::fixed, ios::floatfield);
	cout.setf(ios::showpoint);
	
	result = first_move + second_move;	// adding objects!
	cout << "First move: ";
	first_move.show_vector();		// display first_move
	cout << "Magnitude, angle = ";
	first_move.show_polar();
	cout << "Second move: ";
	second_move.show_vector();
	cout << "Magnitude, angle = ";
	second_move.show_polar();
	cout << "Result: ";
	result.show_vector();
	cout << "Magnitude, angle = ";
	result.show_polar();
	
	Vector twotimes = result * 2.0;	// member function
	cout << "Doubled result: ";
	twotimes.show_vector();

	result = 0.5 * result;		// friend function
	cout << "Halved result: ";
	result.show_vector();
   
	return 0;
}



// vector2.h -- Vector class with <<, mode state

#ifndef _VECTOR2_H_
#define _VECTOR2_H_
class Vector
{
private:   
	double x;          // horizontal value
	double y;          // vertical value
	double mag;        // length of vector
	double ang;        // direction of vector
	char mode;         // 'r' = rectangular, 'p' = polar
	void set_mag(void);
	void set_ang(void);
	void set_x(void);
	void set_y(void);
public:
	Vector(void);
	Vector(double n1, double n2, char form = 'r');
	void set(double n1, double n2, char form = 'r');
	~Vector(void);
	double xval() const {return x;}	// report x value
	double yval() const {return y;}	// report y value
	double magval() const {return mag;}	// report magnitude
	double angval() const {return ang;}	// report angle
	void polar_mode();
	void rect_mode();
// operator overloading
	Vector operator+(const Vector & b) const;
	Vector operator-(const Vector & b) const;
	Vector operator-() const;
	Vector operator*(double n) const;
// friends
	friend Vector operator*(double n, Vector & a);
	friend ostream& operator<<(ostream& os, const Vector & v);
};
#endif



// vector2.cpp -- methods for Vector class

#include <iostream.h>
#include <math.h>
#include "vector2.h"
const double Rad_to_deg = 57.2957795130823;

// private methods
// calculates magnitude from x and y
void Vector::set_mag(void)
{
   mag = sqrt(x * x + y * y);
}

void Vector::set_ang(void)
{
	if (x == 0.0 && y == 0.0)
		ang = 0.0;
	else
		ang = atan2(y, x);
}
// set x from polar coordinate
void Vector::set_x(void)
{
   x = mag * cos(ang);
}

// set y from polar coordinate
void Vector::set_y(void)
{
   y = mag * sin(ang);
}

// public methods
Vector::Vector(void)          // default constructor
{
   x = y = mag = ang = 0.0;
   mode = 'r';
}

// construct vector from rectangular coordinates if form is r
// or else from polar coordinates if form is p
Vector::Vector(double n1, double n2, char form)
{
   mode = form;
   if (form == 'r')
    {
       x = n1;
       y = n2;
       set_mag();
       set_ang();
   }
   else if (form == 'p')
   {
       mag = n1;
       ang = n2 / Rad_to_deg;
       set_x();
       set_y();
   }
   else
   {
       cout << "Incorrect 3rd argument to Vector() -- ";
       cout << "vector set to 0\n";
       x = y = mag = ang = 0.0;
       mode = 'r';
   }
}

// set vector from rectangular coordinates if form is r
// or else from polar coordinates if form is p
void Vector:: set(double n1, double n2, char form)
{
   mode = form;
   if (form == 'r')
    {
       x = n1;
       y = n2;
       set_mag();
       set_ang();
   }
   else if (form == 'p')
   {
       mag = n1;
       ang = n2 / Rad_to_deg;
       set_x();
       set_y();
   }
   else
   {
       cout << "Incorrect 3rd argument to Vector() -- ";
       cout << "vector set to 0\n";
       x = y = mag = ang = 0.0;
       mode = 'r';
   }
}


Vector::~Vector(void)	// destructor
{
}

void Vector::polar_mode()	// set to polar mode
{
   mode = 'p';
}

void Vector::rect_mode()		// set to rectangular mode
{
   mode = 'r';
}

// operator overloading
// add two Vectors
Vector Vector::operator+(const Vector & b) const
{
   double sx, sy;
   sx = x + b.x;
   sy = y + b.y;
   Vector sum = Vector(sx, sy);
   return sum;
}

// substract two Vectors
Vector Vector::operator-(const Vector & b) const
{
   double dx, dy;
   dx = x - b.x;
   dy = y - b.y;
   Vector diff = Vector(dx, dy);
   return diff;
}

// change sign of Vector
Vector Vector::operator-() const
{
   double nx, ny;
   nx = -x;
   ny = -y;
   Vector neg = Vector(nx, ny);
   return neg;
}

// multiply Vector by n
Vector Vector::operator*(double n) const
{
   double mx, my;
   mx = n * x;
   my = n * y;
   Vector mult = Vector(mx, my);
   return mult;
}

// friend methods
// multiply n by Vector a
Vector operator*(double n, const Vector & a)
{
   return a * n;
}

// display rectangular coordinates if mode is r, 
// else display polar coordinates if mode is p
ostream& operator<<(ostream & os, const Vector & v)
{
   if (v.mode == 'r')
       os << "(x,y) = (" << v.x << ", " << v.y << ")";
   else if (v.mode == 'p')
   {
       os << "(m,a) = (" << v.mag << ", "
          << v.ang * Rad_to_deg << ")";
   }
   else
       os << "Vector object mode is invalid";
   return os;
}


// randwalk.cpp -- use the revised Vector class

// compile with the vector2.cpp file
#include <iostream.h>
#include <stdlib.h> 	// rand(), srand() prototypes
#include <time.h>		// time() prototype
#include "vector2.h"
int main(void)
{
	srand(time(0));		// seed random-number generator
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	cout << "Enter target distance (q to quit): ";
	while (cin >> target)
	{
		cout << "Enter step length: ";
		if (!(cin >> dstep))
			break;

		while (result.magval() < target)
		{
			direction = rand() % 360;
			step.set(dstep, direction, 'p');
			result = result + step;
			steps++;
		}
		cout << "After " << steps << " steps, the subject "
			"has the following location:\n";
		cout << result << "\n";
		result.polar_mode();
		cout << " or\n" << result << "\n";
		cout << "Average outward distance per step = "
			<< result.magval()/steps << "\n";
		steps = 0;
		result.set(0.0, 0.0);
		cout << "Enter target distance (q to quit): ";
	}
	cout << "Bye!\n";

	return 0;
}



Automatic Conversions and Type Casts for Classes



// stonewt.h -- definition for Stonewt class

#ifndef _STONEWT_H_
#define _STONEWT_H_
class Stonewt
{
private:
	enum {Lbs_per_stn = 14};	// pounds per stone
	int stone;	// whole stones
	double pds_left;	// fractional pounds
	double pounds;	// entire weight in pounds
public:
	Stonewt(double lbs);	// constructor for double pounds
	Stonewt(int stn, double lbs);	// constructor for stone, lbs
	Stonewt();	// default constructor
	~Stonewt();
	void show_lbs() const;	// show weight in pounds format
	void show_stn() const;	// show weight in stone format
};
#endif



// stonewt.cpp -- Stonewt class methods

#include <iostream.h>
#include "stonewt.h"

// construct Stonewt object from double value
Stonewt::Stonewt(double lbs)
{
	stone = int (lbs) / Lbs_per_stn;	// integer division
	pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
	pounds = lbs;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs)
{
	stone = stn;
	pds_left = lbs;
	pounds =  stn * Lbs_per_stn +lbs;
}

Stonewt::Stonewt()	// default constructor, wt = 0
{
	stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()	// destructor
{
}

// show weight in stones
void Stonewt::show_stn() const
{
	cout << stone << " stone, " << pds_left << " pounds\n";
}

// show weight in pounds
void Stonewt::show_lbs() const
{
	cout << pounds << " pounds\n";
}



// stone.cpp -- user-defined conversions

// compile with stonewt.cpp
#include <iostream.h>
#include "stonewt.h"
void display(Stonewt st, int n);
int main(void)
{
	Stonewt pavarotti = 260;	// uses constructor to initialize
	Stonewt wolfe((double)285.7);	// same as Stonewt wolfe = 285.7;
	Stonewt taft(21, 8);

	cout << "The tenor weighed ";
	pavarotti.show_stn();
	cout << "The detective weighed ";
	wolfe.show_stn();
	cout << "The President weighed ";
	taft.show_lbs();
	pavarotti = double(265.8);		// uses constructor for conversion
	taft = 325;			// same as taft = Stonewt(325);
	cout << "After dinner, the tenor weighed ";
	pavarotti.show_stn();
	cout << "After dinner, the President weighed ";
	taft.show_lbs();
	display(taft, 2);
	cout << "The wrestler weighed even more.\n";
	display(422, 2);
	cout << "No stone left unearned\n";
	return 0;
}

void display(Stonewt st, int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << "Wow! ";
		st.show_stn();
	}
}



// stonewt1.h -- revised definition for Stonewt class

#ifndef _STONEWT1_H_
#define _STONEWT1_H_
class Stonewt
{
private:
	enum {Lbs_per_stn = 14};	// pounds per stone
int stone;	// whole stones
	double pds_left;	// fractional pounds
	double pounds;	// entire weight in pounds
public:
	Stonewt(double lbs);	// construct from double pounds
	Stonewt(int stn, double lbs);  // construct from stone, lbs
	Stonewt();	// default constructor
	~Stonewt();
	void show_lbs() const;	// show weight in pounds format
	void show_stn() const;	// show weight in stone format
// conversion functions
	operator int() const;
	operator double() const;
};
#endif



// stonewt.cpp -- Stonewt class methods

#include <iostream.h>
#include "stonewt1.h"

Stonewt::Stonewt(double lbs)
{
	stone = int (lbs) / Lbs_per_stn;	// integer division
	pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs);
	pounds = lbs;
}

Stonewt::Stonewt(int stn, double lbs)
{
	stone = stn;
	pds_left = lbs;
	pounds =  stn * Lbs_per_stn +lbs;
}

Stonewt::Stonewt()
{
	stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
{
}

void Stonewt::show_stn() const
{
	cout << stone << " stone, " << pds_left << " pounds\n";
}

void Stonewt::show_lbs() const
{
	cout << pounds << " pounds\n";
}
// conversion functions
Stonewt::operator int() const
{
	if (pounds - (int) pounds < 0.5)
		return pounds;
	else
		return pounds + 1;
} 

Stonewt::operator double()const
{
	return pounds;
}



// stone1.cpp -- user-defined conversion functions

// compile with stonewt1.cpp
#include <iostream.h>
#include "stonewt1.h"

int main(void)
{
	Stonewt poppins(9,2.8);		// 9 stone, 2.8 pounds
	double p_wt = poppins;		// implicit conversion
    	cout << "Convert to double => ";
	cout << "Poppins: " << p_wt << " pounds.\n";
	cout << "Convert to int => ";
   	cout << "Poppins: " << int (poppins) << " pounds.\n";
	return 0;
}