/////////////////////////////////////////////////////////////////////
// (C) Michael A Smith 1991-1999 University of Brighton //
// http://www.it.brighton.ac.uk/~mas //
/////////////////////////////////////////////////////////////////////
// ANSI C++ program //
// Version automatically created Mon 09 Jul 2001 21:48:34 BST //
/////////////////////////////////////////////////////////////////////
// Add defined as
// add(T, T, T) rather than T add (T,T)
// Because the return type is not changed in inheritance
// Note fix for T + 1
// 3 @templated functions T + T, T + int, int + T
#include <iostream>
// ---------------------------------------------------------------------
// Specification of Money
// ---------------------------------------------------------------------
// Note the prevention of a converting constructor by using the
// @keyword explicit on the constructor for Money
//
// However if a constructor is used explicitly then normal assignment
// compatible conversions will take place
#include "t99_type.h"
#ifndef CLASS_MONEY_SPEC
#define CLASS_MONEY_SPEC
class Money {
public:
explicit Money( const long = 0L, const int = 0 );
static void add( Money& , Money, Money );
friend std::ostream& operator << (std::ostream&, const Money);
long units() const; // return the units
int hundredths() const; // return the hundredths
private:
long the_credits; // In Units
int the_hundredths; // In Pence
};
// Definition of @inline methods
// As a user of the class you do not want to see these, but ...
inline Money::Money( const long credits, const int pence )
{
the_credits = credits; the_hundredths = pence;
}
inline long Money::units() const
{
return the_credits;
}
inline int Money::hundredths() const
{
return the_hundredths;
}
#endif
// ---------------------------------------------------------------------
// Implementation of Money
// ---------------------------------------------------------------------
#ifndef CLASS_MONEY_IMP
#define CLASS_MONEY_IMP
void Money::add( Money& res, Money lhs, Money rhs)
{
res.the_hundredths = lhs.the_hundredths + rhs.the_hundredths;
res.the_credits = res.the_hundredths / 100;
res.the_hundredths = res.the_hundredths % 100;
res.the_credits = res.the_credits +
lhs.the_credits + rhs.the_credits;
}
std::ostream& operator << ( std::ostream& s, const Money m )
{
s << "#" << m.units() << "."
<< (m.hundredths() < 10 ? "0" : "" )
<< m.hundredths();
return s;
}
#endif
// ---------------------------------------------------------------------
// Forward declaration of classes
// ---------------------------------------------------------------------
class Dollars;
class Pounds;
class Francs;
// ---------------------------------------------------------------------
// Specification of Dollars
// ---------------------------------------------------------------------
#ifndef CLASS_DOLLARS_SPEC
#define CLASS_DOLLARS_SPEC
class Dollars : public Money {
public:
explicit Dollars( const long = 0L, const int = 0 );
static void set_rate( const double, const double );
friend std::ostream& operator << (std::ostream&, Dollars);
operator Pounds() const; // Conversion operator Pounds
operator Francs() const; // Conversion operator Francs
private:
static double the_pounds_rate; // Pounds rate
static double the_franc_rate; // Franc rate
};
#endif
// ---------------------------------------------------------------------
// Specification of Francs
// ---------------------------------------------------------------------
// Still has methods missing if want to work in Francs
#ifndef CLASS_FRANCS_SPEC
#define CLASS_FRANCS_SPEC
class Francs : public Money {
public:
explicit Francs( const long = 0, const int = 0);
friend std::ostream& operator << (std::ostream&, Francs);
static void set_rate( const double, const double );
operator Dollars() const; // Conversion operator Francs
operator Pounds() const; // Conversion operator Pounds
private:
static double the_pound_rate; // Pounds rate
static double the_dollar_rate; // Dollar rate
};
#endif
// ---------------------------------------------------------------------
// Specification of Pounds
// ---------------------------------------------------------------------
#ifndef CLASS_POUNDS_SPEC
#define CLASS_POUNDS_SPEC
class Pounds : public Money {
public:
static void set_rate( const double, const double );
explicit Pounds( const long = 0L, const int = 0 );
operator Dollars() const; // Conversion operator Dollars
operator Francs() const; // Conversion operator Francs
friend std::ostream& operator << ( std::ostream& s, Pounds m );
private:
static double the_dollar_rate; // Dollar rate
static double the_franc_rate; // Franc rate
};
#endif
// ---------------------------------------------------------------------
// Implementation of Pounds
// ---------------------------------------------------------------------
#ifndef CLASS_POUNDS_IMP
#define CLASS_POUNDS_IMP
#define exception Xexception // Uses name
#include <math.h>
#define Xexception exception // Uses name
double Pounds::the_dollar_rate = 1.0;
double Pounds::the_franc_rate = 1.0;
Pounds::Pounds( const long pounds, const int pence ) :
Money( pounds, pence )
{
}
void Pounds::set_rate( const double dollar_rate, const double franc_rate )
{
the_dollar_rate = dollar_rate;
the_franc_rate = franc_rate;
}
Pounds::operator Dollars() const
{
long pence = (long) floor( the_dollar_rate * hundredths() +
the_dollar_rate * units() * 100.0 + 0.5);
long units = pence / 100;
pence = pence % 100;
return Dollars( units, pence );
}
Pounds::operator Francs() const
{
long centime = (long) floor( the_franc_rate * hundredths() +
the_franc_rate * units() * 100.0 + 0.5 );
long units = centime / 100;
centime = centime % 100;
return Francs( units, centime );
}
std::ostream& operator << ( std::ostream& s, Pounds m )
{
s << "L" << m.units() << "."
<< (m.hundredths() < 10 ? "0" : "" )
<< m.hundredths();
return s;
}
#endif
// ---------------------------------------------------------------------
// Implementation of Francs
// ---------------------------------------------------------------------
#ifndef CLASS_FRANCS_IMP
#define CLASS_FRANCS_IMP
#define exception Xexception // Uses name
#include <math.h>
#define Xexception exception // Uses name
double Francs::the_dollar_rate = 1.0;
double Francs::the_pound_rate = 1.0;
Francs::Francs(const long francs, const int centime) :
Money( francs, centime )
{
}
void Francs::set_rate( const double dollar_rate, const double pound_rate )
{
the_dollar_rate = dollar_rate;
the_pound_rate = pound_rate;
}
Francs::operator Dollars() const
{
long cents = (long) floor( the_dollar_rate * hundredths() +
the_dollar_rate * units() * 100.0 + 0.5);
long dollars = cents / 100;
cents = cents % 100;
return Dollars( dollars, cents );
}
Francs::operator Pounds() const
{
long pence = (long) floor( the_pound_rate * hundredths() +
the_pound_rate * units() * 100.0 + 0.5 );
long pounds = pence / 100;
pence = pence % 100;
return Pounds( pounds, pence );
}
std::ostream& operator << ( std::ostream& s, Francs m )
{
s << "SFr" << m.units() << "."
<< (m.hundredths() < 10 ? "0" : "" )
<< m.hundredths();
return s;
}
#endif
// ---------------------------------------------------------------------
// Implementation of Dollars
// ---------------------------------------------------------------------
#ifndef CLASS_DOLLARS_IMP
#define CLASS_DOLLARS_IMP
#define exception Xexception // Uses name
#include <math.h>
#define Xexception exception // Uses name
double Dollars::the_pounds_rate = 1.0;
double Dollars::the_franc_rate = 1.0;
Dollars::Dollars( const long dollars, const int cents) :
Money( dollars, cents )
{
}
void Dollars::set_rate( const double pounds_rate, const double franc_rate )
{
the_pounds_rate = pounds_rate;
the_franc_rate = franc_rate;
}
std::ostream& operator << ( std::ostream& s, Dollars m )
{
s << "$" << m.units() << "."
<< (m.hundredths() < 10 ? "0" : "" )
<< m.hundredths();
return s;
}
Dollars::operator Pounds() const
{
long pence = (long) floor( the_pounds_rate * hundredths() +
the_pounds_rate * units() * 100.0 + 0.5 );
long pounds = pence / 100;
pence = pence % 100;
return Pounds( pounds, pence );
}
Dollars::operator Francs() const
{
long centime = (long) floor( the_franc_rate * hundredths() +
the_franc_rate * units() * 100.0 + 0.5);
long francs = centime / 100;
centime = centime % 100;
return Francs( francs, centime );
}
#endif
// ---------------------------------------------------------------------
template <class Type>
inline Type operator + ( Type lhs, Type rhs )
{
Type res;
Type::add( res, lhs, rhs );
return res;
}
/*
template <class Type1, class Type2>
inline Type1 operator + ( Type1 lhs, Type2 rhs )
{
Type res;
Type::add( res, (Type1) lhs, rhs );
return res;
}
*/
template <class Type>
inline Type operator + ( Type lhs, int rhs )
{
Type res;
Type::add( res, lhs, Type(rhs) );
return res;
}
template <class Type>
inline Type operator + ( int lhs, Type rhs )
{
Type res;
Type::add( res, Type(lhs), rhs );
return res;
}
// ---------------------------------------------------------------------
#include <iomanip>
// ---------------------------------------------------------------------
int main1(); int main2(); int main3();
int main4(); int main5(); int main6();
int main7(); int main8(); int main9();
int main10();
int main()
{
const double Dollar_Pound_rate = 0.6105; // Dollars -> Pound
const double Dollar_Franc_rate = 1.4613; // Dollars -> Swiss Francs
Dollars::set_rate( Dollar_Pound_rate, Dollar_Franc_rate );
// The money market would have precise rates which would
// allow a small profit on conversions
const double Pound_Dollar_rate = 1/Dollar_Pound_rate;
const double Pound_Franc_rate = Pound_Dollar_rate * Dollar_Franc_rate;
Pounds::set_rate( Pound_Dollar_rate, Pound_Franc_rate );
const double Franc_Dollar_rate = 1/Pound_Franc_rate*Pound_Dollar_rate;
const double Franc_Pound_rate = 1/Pound_Franc_rate;
Francs::set_rate( Franc_Dollar_rate, Franc_Pound_rate );
std::cout << "Example 1 " << "\n"; main1();
std::cout << "Example 2 " << "\n"; main2();
std::cout << "Example 3 " << "\n"; main3();
std::cout << "Example 4 " << "\n"; main4();
std::cout << "Example 5 " << "\n"; main5();
std::cout << "Example 6 " << "\n"; main6();
std::cout << "Example 7 " << "\n"; main7();
std::cout << "Example 8 " << "\n"; main8();
std::cout << "Example 9 " << "\n"; main9();
std::cout << "Example 10" << "\n"; main10();
return 0;
}
int main1()
{
std::cout << std::setiosflags( std::ios::fixed ); // Format x.y
std::cout << std::setiosflags( std::ios::showpoint ); // 0.10
std::cout << std::setprecision(2); // 2 dec places
std::cout << "Dollars" << "\n";
Dollars in_dollars(100,00);
Francs in_francs;
in_francs = in_dollars;
std::cout << "Holiday money = " << in_dollars << "\n";
std::cout << "Holiday money = " << in_francs << "\n";
std::cout << "Holiday money = " << in_dollars << "\n";
std::cout << "Holiday money = " << (Francs) in_dollars << "\n";
std::cout << "Dollars" << "\n";
Dollars money_in_dollars( 100, 00 );
Pounds money_in_pounds = money_in_dollars;
Francs money_in_francs = money_in_dollars;
std::cout << "Dollars : " << money_in_dollars << "\n";
std::cout << " Francs " << money_in_francs << "\n";
std::cout << " Pounds " << money_in_pounds << "\n";
std::cout << "Pounds : " << money_in_pounds << "\n";
std::cout << " Dollars " << (Dollars) money_in_pounds << "\n";
std::cout << " Francs " << (Francs) money_in_pounds << "\n";
std::cout << "Francs : " << money_in_francs << "\n";
std::cout << " Dollars " << (Dollars) money_in_francs << "\n";
std::cout << " Pounds " << (Pounds) money_in_francs << "\n";
//
money_in_dollars = Dollars(100,00);
std::cout << "Dollars : " << money_in_dollars << "\n";
std::cout << " Francs " << money_in_francs << "\n";
std::cout << " Pounds " << money_in_pounds << "\n";
money_in_pounds = Pounds(100,00);
std::cout << "Pounds : " << money_in_pounds << "\n";
std::cout << " Dollars " << (Dollars) money_in_pounds << "\n";
std::cout << " Francs " << (Francs) money_in_pounds << "\n";
money_in_francs = Francs(100,00);
std::cout << "Francs : " << money_in_francs << "\n";
std::cout << " Dollars " << (Dollars) money_in_francs << "\n";
std::cout << " Pounds " << (Pounds) money_in_francs << "\n";
//Money wrong = 10; // Does not compile
Money mike(10,'a'); // Dubious
//mike = mike + 1; // Does not compile GCC
return 0;
}
void process(); // Process monetary transactions
int main2()
{
const double Dollar_Pound_rate = 0.6105; // Dollars -> Pound
const double Dollar_Franc_rate = 1.4613; // Dollars -> Swiss Francs
Dollars::set_rate( Dollar_Pound_rate, Dollar_Franc_rate );
// The money market would have precise rates which would
// allow a small profit on conversions
const double Pound_Dollar_rate = 1/Dollar_Pound_rate;
const double Pound_Franc_rate = Pound_Dollar_rate * Dollar_Franc_rate;
Pounds::set_rate( Pound_Dollar_rate, Pound_Franc_rate );
const double Franc_Dollar_rate = 1/Pound_Franc_rate*Pound_Dollar_rate;
const double Franc_Pound_rate = 1/Pound_Franc_rate;
Francs::set_rate( Franc_Dollar_rate, Franc_Pound_rate );
process();
return 0;
}
void process()
{
std::cout << "In Dollars" << "\n";
Dollars to_pay(100,0);
std::cout << "Amount to pay = " << to_pay << "\n";
std::cout << "Amount to pay = " << (Pounds) to_pay << "\n";
std::cout << "Amount to pay = " << (Francs) to_pay << "\n";
Dollars discount( 1,0 );
Dollars sum = Dollars(5,0) + Dollars(5,0);
Dollars sum2 = to_pay + discount;
std::cout << sum << "\n";
std::cout << (Pounds) ( Dollars(5,0) + Dollars(5,0) ) << "\n";
}
int main3()
{
Money *mine = new Money;
Money *also = new Money(1,2);
Money *lots = new Money[10];
Dollars *yours = new Dollars;
Dollars *more = new Dollars[10];
*mine = lots[2] = *mine = *also;
*yours= more[2] = *yours;
std::cout << "cout << " << *also << "\n";
std::cerr << "cerr << " << *also << "\n";
delete mine; delete also; delete [] lots;
delete yours; delete [] more;
Money to_spend( 1 , 'A' ); // Type conversion
/*
to_spend = 'A'; // Assignment compatible conversion
to_spend = 10L; // Assignment compatible conversion
to_spend = 10; // Assignment compatible conversion
*/
return 0;
}
int main4()
{
Money ham_pizza(4,75);
Money extra_cheese = Money(0,50);
Money tuna_pizza = ham_pizza + 1;
std::cout << "A ham pizza costs " << ham_pizza << "\n";
std::cout << "A ham pizza with extra cheese costs " <<
(ham_pizza+extra_cheese) << "\n";
std::cout << "A tuna pizza costs " << tuna_pizza << "\n";
return 0;
}
int main5()
{
Dollars ham_pizza(4,75);
Dollars extra_cheese = Dollars(0,50);
Dollars tuna_pizza = ham_pizza + 1;
std::cout << "A ham pizza costs " << ham_pizza << "\n";
std::cout << "A ham pizza with extra cheese costs " <<
(ham_pizza+extra_cheese) << "\n";
std::cout << "A tuna pizza costs " << tuna_pizza << "\n";
return 0;
}
int main6()
{
Dollars old_asset(10,0);
Dollars new_asset = (Dollars) (Pounds) old_asset;
std::cout << "old_asset : " << old_asset << "\n";
std::cout << "new_asset : " << new_asset << "\n";
std::cout << "Should be the same!!" << "\n";
Pounds x1 = (Pounds) old_asset;
Dollars x3 = (Dollars) x1;
std::cout << "Pounds : " << x1 << "\n";
std::cout << "Dollars : " << x3 << "\n";
return 0;
}
int main7()
{
std::cout << "In Pounds" << "\n";
Pounds to_pay(10,0);
std::cout << "Amount to pay = " << to_pay << "\n";
std::cout << "Amount to pay = " << (Dollars) to_pay << "\n";
std::cout << "Amount to pay = " << (Francs) to_pay << "\n";
Pounds sum = Pounds(5,0) + Pounds(5,0);
std::cout << sum << "\n";
std::cout << (Pounds(5,0) + Pounds(5,0)) << "\n";
return 0;
}
int main8()
{
Dollars camera(60,50);
Dollars bag(9,99);
std::cout << "Cost of camera : " << camera << "\n";
std::cout << "Cost of bag : " << bag << "\n";
std::cout << "Cost of camera + bag is : ";
Dollars res; Money::add( res, camera, bag );
std::cout << res << "\n";
return 0;
}
int main9()
{
Dollars camera(60,50);
Dollars bag(9,99);
std::cout << "Cost of camera : " << camera << "\n";
std::cout << "Cost of bag : " << bag << "\n";
std::cout << "Cost of camera + bag is : " << (camera + bag) << "\n";
return 0;
}
// Neat
// But ambiguity between type + 1
template <class Type1, class Type2>
inline Type1 operator + ( Type1 lhs, Type2 rhs )
{
Type1 res;
Type1::add( res, lhs, (Type1) rhs );
return res;
}
int main10()
{
Dollars camera(60,50);
Pounds bag(9,99);
std::cout << "Cost of camera : " << camera << "\n";
std::cout << "Cost of bag : " << bag << "\n";
std::cout << "Cost of camera + bag is : " << (camera + bag) << "\n";
return 0;
}
|
© M.A.Smith University of Brighton.
Created February 1999 Last modified March 1999 Version 1.1
Comments, suggestions, etc. M.A.Smith at brighton dot ac dot uk [Home page] Printed / Displayed |