Classes Inheritance |
|---|
// arraydb.h -- define array class
#ifndef _ARRAYDB_H_
#define _ARRAYDB_H_
#include <iostream.h>
class ArrayDb
{
private:
unsigned int size; // number of array elements
protected:
double * arr; // address of first element
public:
ArrayDb(); // default constructor
// create an ArrayDb of n elements, set each to val
ArrayDb(unsigned int n, double val = 0.0);
// create an ArrayDb of n elements, initialize to array pn
ArrayDb(const double * pn, unsigned int n);
ArrayDb(const ArrayDb & a); // copy constructor
~ArrayDb(); // destructor
unsigned int arsize() const {return size;} // returns array size
// overloaded operators
double & operator[](int i); // array indexing
const double & operator[](int i) const; // array indexing (no =)
ArrayDb & operator=(const ArrayDb & a);
friend ostream & operator<<(ostream & os, const ArrayDb & a);
};
#endif
// arraydb.cpp -- ArrayDb class methods
#include <iostream.h>
#include <stdlib.h> // exit() prototype
#include "arraydb.h"
// default constructor -- no arguments
ArrayDb::ArrayDb()
{
arr = NULL;
size = 0;
}
// constructs array of n elements, each set to val
ArrayDb::ArrayDb(unsigned int n, double val)
{
arr = new double[n];
size = n;
for (int i = 0; i < size; i++)
arr[i] = val;
}
// initialize ArrayDb object to a non-class array
ArrayDb::ArrayDb(const double *pn, unsigned int n)
{
arr = new double[n];
size = n;
for (int i = 0; i < size; i++)
arr[i] = pn[i];
}
// initialize ArrayDb object to another ArrayDb object
ArrayDb::ArrayDb(const ArrayDb & a)
{
size = a.size;
arr = new double[size];
for (int i = 0; i < size; i++)
arr[i] = a.arr[i];
}
ArrayDb::~ArrayDb()
{
delete [] arr;
}
// let user access elements by index (assignment allowed)
double & ArrayDb::operator[](int i)
{
// check index before continuing
if (i < 0 || i >= size)
{
cerr << "Error in array limits: "
<< i << " is a bad index\n";
exit(1);
}
return arr[i];
}
// let user access elements by index (assignment disallowed)
const double & ArrayDb::operator[](int i) const
{
// check index before continuing
if (i < 0 || i >= size)
{
cerr << "Error in array limits: "
<< i << " is a bad index\n";
exit(1);
}
return arr[i];
}
// define class assignment
ArrayDb & ArrayDb::operator=(const ArrayDb & a)
{
if (this == &a) // if object assigned to self,
return *this; // don't change anything
delete arr;
size = a.size;
arr = new double[size];
for (int i = 0; i < size; i++)
arr[i] = a.arr[i];
return *this;
}
// quick output, 5 values to a line
ostream & operator<<(ostream & os, const ArrayDb & a)
{
for (int i = 0; i < a.size; i++)
{
os << a.arr[i] << " ";
if (i % 5 == 4)
os << "\n";
}
if (i % 5 != 0)
os << "\n";
return os;
}
// tinsel.cpp -- use the ArrayDb class
// compile with arraydb.cpp
#include <iostream.h>
#include "arraydb.h"
void display(ArrayDb & ar);
int main(void)
{
cout << "Enter number of regions: ";
unsigned int regions; // read number of regions
cin >> regions;
ArrayDb tons(regions); // create an "array" of that size
cout << "Enter the regional tinsel sales in tons:\n";
for (int i = 0; i < regions; i++)
{
cout << "Region " << (i+ 1) << ": ";
cin >> tons[i]; // use array notation
}
ArrayDb dup; // default object
dup = tons; // array assignment
cout << "Here's the original data:\n" << tons;
cout << "Here's the copy:\n";
display(dup); // pass array without passing size
double wts[5] = {155.2, 189.6, 174.3, 256.9, 203.5};
ArrayDb bod(wts, 5); // initialize an ArrayDb to an array
cout << "Here are the weights of the Board of Directors:\n"
<< bod;
// try to exceed array limit
cout << "Index: value\n";
for (i = 0; i <= regions; i++)
{
cout.width(5);
cout << i << ": " << tons[i] << "\n";
}
return 0;
}
void display(ArrayDb & ar)
{
cout << "copy!\n";
cout << ar;
cout << "copy!\n";
}
// aritharr.h -- derived array class with more arithmetic
#ifndef _ARITHARR_H_
#define _ARITHARR_H_
#include "arraydb.h"
class ArithArr : public ArrayDb // derived from ArrayDb class
{
private:
// no new data members
public:
// base class constructors not inherited,
// need ArrithArr constructors
ArithArr(){}
ArithArr(unsigned int n, double val = 0.0)
: ArrayDb(n, val) {}
ArithArr(const double *pn, unsigned int n)
: ArrayDb(pn, n) {}
ArithArr(const ArithArr & aa) : ArrayDb(aa) {}
ArithArr(const ArrayDb & ad) : ArrayDb(ad) {}
// destructor ArrrayDb part is inherited, but you can define a new one
~ArithArr() {}
// new methods
double sum() const;
double average() const;
// overloaded operators
ArithArr operator+(const ArithArr & a) const;
ArithArr operator-(const ArithArr & a) const;
ArithArr operator-() const;
ArithArr operator*(const ArithArr & a) const;
ArithArr operator*(double d) const;
friend ArithArr operator*(double d, const ArithArr & a)
};
#endif
// aritharr.cpp -- ArithArr class methods
#include <iostream.h>
#include <stdlib.h> // exit() prototype
#include "aritharr.h"
// new methods
double ArithArr::sum() const
{
unsigned int size = arsize(); // access base via method
double total = 0.0;
for (int i = 0; i < size; i++)
total += arr[i]; // access base directly
return total;
}
double ArithArr::average() const
{
unsigned int size = arsize();
if (size < 1)
{
cout << "Computing an average requires at least "
"one array element -- bye.\n";
exit(1);
}
return sum() / size;
}
// overloaded operators
ArithArr ArithArr::operator+(const ArithArr & a) cons
{
unsigned int size = arsize();
unsigned int asize = a.arsize();
if (size != asize)
{
cerr << "+ not defined for arrays of unequal size\n";
exit(1);
}
ArithArr total(size);
for (int i = 0; i < size; i++)
total[i] = arr[i] + a.arr[i];
return total;
}
ArithArr ArithArr::operator-(const ArithArr & a) const
{
unsigned int size = arsize();
unsigned int asize = a.arsize()
if (size != asize)
{
cerr << "- not defined for arrays of unequal size\n";
exit(1);
}
ArithArr diff(size);
for (int i = 0; i < size; i++)
diff[i] = arr[i] - a.arr[i];
return diff;
}
ArithArr ArithArr::operator-() const
{
unsigned int size = arsize();
ArithArr neg(size);
for (int i = 0; i < size; i++)
neg[i] = -arr[i];
return neg;
}
ArithArr ArithArr::operator*(const ArithArr & a) const
{
unsigned int size = arsize();
unsigned int asize = a.arsize();
if (size != asize)
{
cout << "Array multiplication error: arrays must "
"be of same size. Bye.\n";
exit(1);
}
ArithArr product(size);
for (int i = 0; i < size; i++
product[i] = arr[i] * a.arr[i];
return product;
}
ArithArr ArithArr::operator*(double d) const
{
unsigned int size = arsize();
ArithArr temp(size);
for (int i = 0; i < size; i++
temp[i] = arr[i]*d
return temp;
}
ArithArr operator*(double d, const ArithArr & a)
{
return a*d;
}
// derived.cpp -- use a derived class
// compile with aritharr.cpp and arraydb.cpp
#include <iostream.h>
#include <stdlib.h> // exit() prototype
#include "aritharr.h"
void show(const ArrayDb & ar, int index);
const int things = 4;
double price[things] = { 9.95, 28.55, 8.99, 1.50 };
int main(void)
{
ArithArr prices1(price, things);
ArithArr prices2(prices1);
prices2 = 1.05 * prices1; // multiplication, assignment
ArithArr sales1(things);
ArithArr sales2(things);
cout << "Enter sales for first half:\n"
<< "disks mitts tapes cards\n";
for (int i = 0; i < things; i++)
cin >> sales1[i];
cout << "Enter sales for second half:\n"
<< "disks mitts tapes cards\n";
for (i = 0; i < things; i++)
cin >> sales2[i];
ArithArr allsales = sales1 + sales2;
cout << "Total sales:\n" << allsales;
ArithArr gross = sales1 * prices1 + sales2 * prices2;
cout.precision(2); // 2 places to right of decimal
cout.setf(ios::showpoint); // show trailing 0s
cout.setf(ios::fixed, ios::floatfield); // fixed point
cout << "Gross take in dollars per item:\n" << gross;
cout << "Let's see that with a $:\n";
for (i = 0; i < things; i++)
show(gross, i); // ArrayDb reference
cout << "Total gross: $" << gross.sum() << "\n";
return 0;
}
void show(const ArrayDb & ar, int index)
{
cout << index << ": $" << ar[index] << "\n";
}
// limarr.h -- LimitArr class
#ifndef _LIMARR_H_
#define _LIMARR_H_
#include "arraydb.h"
class LimitArr : public ArrayDb
{
protected:
unsigned int low_bnd; // new data member
void ok(int i) const; // handle bounds checking
public:
// constructors
LimitArr();
LimitArr(unsigned int n, double val = 0.0);
LimitArr(unsigned int n, int lb, double val = 0.0);
LimitArr(const double * pn, unsigned int n);
LimitArr(const LimitArr & a);
LimitArr(const ArrayDb & a);
// new methods
void new_lb(int lb) {low_bnd = lb; } // reset lower bound
int lbound() {return low_bnd;} // return lower bound
int ubound() {return low_bnd + arsize() -1;} // return upper bound
// redefined operators
double & operator[](int i);
const double & operator[](int i) const;
};
#endif
// limarr.cpp -- LimitArr methods
#include "limarr.h"
#include <iostream.h>
#include <stdlib.h>
// private method
// lower bound for array index is now low_bnd, and
// upper bound is now low_bnd + size - 1
void LimitArr::ok(int i) const // variable lower bound
{
unsigned long size = arsize();
if (i < low_bnd)
{
cout << "Error in array limits:\n"
<< "index " << i << " less than "
<< low_bnd << "\n";
exit(2);
}
else if (i >= size + low_bnd)
{
cout << "Error in array limits:\n"
<< "index " << i << " greater than "
<< size + low_bnd - 1 << "\n";
exit(3);
}
}
// constructors -- initialize the new data member
LimitArr::LimitArr() : ArrayDb()
{
low_bnd = 0; // default sets starting subscript to 0
}
LimitArr::LimitArr(unsigned int n, double val) : ArrayDb(n, val)
{
low_bnd = 0; // default value
}
LimitArr::LimitArr(unsigned int n, int lb, double val)
: ArrayDb(n, val)
{
low_bnd = lb; // set starting subscript explicitly
}
LimitArr::LimitArr(const double * pn, unsigned int n)
: ArrayDb(pn, n)
{
low_bnd = 0;
}
LimitArr::LimitArr(const LimitArr & a) : ArrayDb(a)
{
low_bnd = a.low_bnd;
}
LimitArr::LimitArr(const ArrayDb & a) : ArrayDb(a)
{
low_bnd = 0;
}
// redefined operators
double & LimitArr::operator[](int i)
{
ok(i);
return arr[i - low_bnd];
}
const double & LimitArr::operator[](int i) const
{
ok(i);
return arr[i - low_bnd];
}
// use_lim.cpp -- use the LimitArr class
// Compile with limarr.cpp and arraydb.cpp
#include <iostream.h>
#include "limarr.h"
void show(const ArrayDb & ar, int index);
const int YEAR = 1977;
const int YEARS = 5;
int main(void)
{
LimitArr vintages(YEARS, YEAR);
cout << "Enter bids for the following vintages of "
"Chateau Spiff:\n";
for (int year = YEAR; year < YEAR + YEARS; year++)
{
cout << "Year " << year << ": $";
cin >> vintages[year];
}
cout.precision(2);
cout.setf(ios::showpoint);
cout.setf(ios::fixed, ios::floatfield);
cout << "Recapitulating, here are the bids in dollars:\n";
cout << vintages;
cout << vintages[1978] << "\n";
cout << "The following bids were accepted:\n";
LimitArr copy;
copy = vintages;
int bid1 = 1978;
int bid2 = 1980;
cout << bid1 << ": $" << copy[bid1] << "\n";
show(copy, bid2);
return 0;
}
void show(const ArrayDb & ar, int index)
{
cout << index << ": $" << ar[index] << "\n";
}
// arraydb.h -- revised array class, making [] virtual
#ifndef _ARRAYDB_H_
#define _ARRAYDB_H_
#include <iostream.h>
class ArrayDb
{
private:
unsigned int size; // number of array elements
protected:
double * arr; // address of first element
public:
ArrayDb(); // default constructor
// create an ArrayDb of n elements, set each to val
ArrayDb(unsigned int n, double val = 0.0);
// create an ArrayDb of n elements, initialize to array pn
ArrayDb(const double * pn, unsigned int n);
ArrayDb(const ArrayDb & a); // copy constructor
virtual ~ArrayDb(); // destructor
unsigned int arsize() const {return size;} // returns array size
// overloaded operators -- note use of keyword virtual
virtual double & operator[](int i); // array indexing
virtual const double & operator[](int i) const;// array indexing (no =)
ArrayDb & operator=(const ArrayDb & a);
friend ostream & operator<<(ostream & os, const ArrayDb & a);
};
#endif