Reusing Code in C++ |
|---|
// studentc.h -- defining a Student class using containment
#ifndef _STUDNTC_H_
#define _STUDENTC_H_
#include <iostream.h>
#include "aritharr.h" // from Chapter 12
#include "strng2.h" // from Chapter 11
class Student
{
private:
String name;
ArithArr scores;
public:
Student() : name("Null Student"), scores() {}
Student(const String & s)
: name(s), scores() {}
Student(int n) : name("Nully"), scores(n) {}
Student(const String & s, int n)
: name(s), scores(n) {}
Student(const String & s, const ArithArr & a)
: name(s), scores(a) {}
Student(const char * str, const double * pd, int n)
: name(str), scores(pd, n) {}
~Student() {}
double & operator[](int i);
const double & operator[](int i) const;
double average() const;
// friends
friend ostream & operator<<(ostream & os, const Student & stu);
friend istream & operator>>(istream & os, Student & su);
};
#endif
// studentc.cpp -- student class
#include "studentc.h"
double Student::average() const
{
return scores.average();
}
double & Student::operator[](int i)
{
return scores[i];
}
const double & Student::operator[](int i) const
{
return scores[i];
}
// friends
ostream & operator<<(ostream & os, const Student & stu)
{
os << "Scores for " << stu.name << ":\n";
os << stu.scores;
return os;
}
istream & operator>>(istream & is, Student & stu)
{
is >> stu.name;
return is;
}
// studenti.h -- defining a Student class using private inheritance
#ifndef _STUDNTI_H_
#define _STUDENTI_H_
#include <iostream.h>
#include "aritharr.h"
#include "strng2.h"
class Student : private String, private ArithArr
{
public:
Student() : String("Null Student"), ArithArr() {}
Student(const String & s)
: String(s), ArithArr() {}
Student(int n) : String("Nully"), ArithArr(n) {}
Student(const String & s, int n)
: String(s), ArithArr(n) {}
Student(const String & s, const ArithArr & a)
: String(s), ArithArr(a) {}
Student(const char * str, const double * pd, int n)
: String(str), ArithArr(pd, n) {}
~Student() {}
double & operator[](int i);
const double & operator[](int i) const;
double average() const;
// friends
friend ostream & operator<<(ostream & os, const Student & stu);
friend istream & operator>>(istream & os, Student & su);
};
#endif
// studenti.cpp -- a student class using private inheritance
#include "studenti.h"
double Student::average() const
{
return ArithArr::average();
}
double & Student::operator[](int i)
{
return ArithArr::operator[](i);
}
const double & Student::operator[](int i) const
{
return ArithArr::operator[](i);
}
// friends
ostream & operator<<(ostream & os, const Student & stu)
{
os << "Scores for " << (const String &) stu << ":\n";
os << (const ArithArr &) stu;
return os;
}
istream & operator>>(istream & is, Student & stu)
{
is >> (String &) stu;
return is;
}
// use_stui.cpp -- use a class with private derivation
// compile with studenti.cpp, strng2.cpp, arraydb.cpp, and aritharr.cpp
#include <iostream.h>
#include "studenti.h"
void set(Student & sa, int n);
const int pupils = 3;
const int quizzes = 5;
int main(void)
{
Student ada[pupils] = {quizzes, quizzes, quizzes};
for (int i = 0; i < pupils; i++)
set(ada[i], quizzes);
for (i = 0; i < pupils; i++)
{
cout << "\n" << ada[i];
cout << "average: " << ada[i].average() << "\n";
}
return 0;
}
void set(Student & sa, int n)
{
cout << "Please enter the student's name: ";
cin >> sa;
cout << "Please enter " << n << " quiz scores:\n";
for (int i = 0; i < n; i++)
cin >> sa[i];
while (cin.get() != '\n')
continue;
}
// stacktp.h #include "booly.h" templateclass Stack { private: enum {MAX = 10}; // constant specific to class Type items[MAX]; // holds stack items int top; // index for top stack item public: Stack(); Bool isempty(); Bool isfull(); Bool push(const Type & item); // add item to stack Bool pop(Type & item); // pop top into item }; template Stack ::Stack() { top = 0; } template Bool Stack ::isempty() { return top == 0? True: False; } template Bool Stack ::isfull() { return top == MAX? True :False; } template Bool Stack ::push(const Type & item) { if (top < MAX) { items[top++] = item; return True; } else return False; } template Bool Stack ::pop(Type & item) { if (top > 0) { item = items[--top]; return True; } else return False; } // stacktem.cpp -- test template stack class // compiler with strng2.cpp #include <iostream.h> #include <ctype.h> #include "stacktp.h" #include "strng2.h" int main(void) { Stack st; // create an empty stack char c; String po; cout << "Please enter A to add a purchase order,\n" << "P to process a PO, or Q to quit.\n"; while (cin >> c && toupper(c) != 'Q') { while (cin.get() != '\n') continue; if (!isalpha(c)) { cout << '\a'; continue; } switch(c) { case 'A': case 'a': cout << "Enter a PO number to add: "; cin >> po; if (st.isfull()) cout << "stack already full\n"; else st.push(po); break; case 'P': case 'p': if (st.isempty()) cout << "stack already empty\n"; else { st.pop(po); cout << "PO #" << po << " popped\n"; break; } } cout << "Please enter A to add a purchase order,\n" << "P to process a PO, or Q to quit.\n"; } cout << "Bye\n"; return 0; } // stcktp1.h #include "booly.h" template class Stack { private: enum {MAX = 10}; // constant specific to class int stacksize; Type * items; // holds stack items int top; // index for top stack item public: Stack(int ss = MAX); ~Stack() { delete [] items; } Bool isempty() { return top == 0? True: False; } Bool isfull() { return top == stacksize? True :False; } Bool push(const Type & item); // add item to stack Bool pop(Type & item); // pop top into item }; template Stack ::Stack(int ss) : stacksize(ss), top(0) { items = new Type [stacksize]; } template Bool Stack ::push(const Type & item) { if (top < stacksize) { items[top++] = item; return True; } else return False; } template Bool Stack ::pop(Type & item) { if (top > 0) { item = items[--top]; return True; } else return False; } // stkoptr1.cpp -- test stack of pointers #include <iostream.h> #include <stdlib.h> // for rand(), srand() #include <time.h> // for time() #include "stcktp1.h" const int Stacksize = 4; const int Num = 10; int main(void) { srand(time(0)); // randomize rand() cout << "Please enter stack size: "; int stacksize; cin >> stacksize; Stack st(stacksize); // create an empty stack with 4 slots char * in[Num] = { " 1: Hank Gilgamesh", " 2: Kiki Ishtar", " 3: Betty Rocker", " 4: Ian Flagranti", " 5: Wolfgang Kibble", " 6: Portia Koop", " 7: Joy Almondo", " 8: Xaverie Paprika", " 9: Juan Moore", "10: Misha Mache" }; char * out[Num]; int processed = 0; int nextin = 0; while (processed < Num) { if (st.isempty()) st.push(in[nextin++]); else if (st.isfull()) st.pop(out[processed++]); else if (rand() % 2 && nextin < Num) // 50-50 chance st.push(in[nextin++]); else st.pop(out[processed++]); } for (int i = 0; i < Num; i++) cout << out[i] << "\n"; cout << "Bye\n"; return 0; } //arraytp.h -- Array Template template class ArrayTP { private: T ar[n]; public: ArrayTP(); ArrayTP(const T & v); virtual T & operator[](int i) { return ar[i]; } virtual const T & operator[](int i) const { return ar[i]; } }; template ArrayTP ::ArrayTP() { for (int i = 0; i < n; i++) ar[i] = 0; }; template ArrayTP ::ArrayTP(const T & v) { for (int i = 0; i < n; i++) ar[i] = v; }; // worker.h -- working classes #include "strng2.h" class Worker { private: String fullname; long id; protected: virtual void data() const; public: Worker() : fullname("no one"), id(0L) {} Worker(const String & s, long n) : fullname(s), id(n) {} virtual void set(); virtual void show() const; }; class Waiter : public Worker { private: int panache; protected: void data() const; public: Waiter() : Worker(), panache(0) {} Waiter(const String & s, long n, int p = 0) : Worker(s, n), panache(p) {} Waiter(const Worker & wk, int p = 0) : Worker(wk), panache(p) {} void set(); void show() const; }; class SingingWaiter : public Waiter { protected: enum {other, alto, contralto, soprano, bass, baritone, tenor}; enum {Vtypes = 7}; void data() const; private: static char *pv[Vtypes]; // string equivs of voice types int voice; public: SingingWaiter() : Waiter(), voice(other) {} SingingWaiter(const String & s, long n, int p = 0, int v = other) : Waiter(s, n, p), voice(v) {} SingingWaiter(const Worker & wk, int p = 0, int v = other) : Waiter(wk,p), voice(v) {} SingingWaiter(const Waiter & wt, int v = other) : Waiter(wt), voice(v) {} void set(); void show() const; }; // worker.cpp -- working class methods #include "worker.h" #include <iostream.h> // Worker methods void Worker::set() { cout << "Enter worker's name: "; cin >> fullname; cout << "Enter worker's ID: "; cin >> id; while (cin.get() != '\n') continue; } void Worker::show() const { cout << "Category: worker\n"; data(); } // protected method void Worker::data() const { cout << "Name: " << fullname << "\n"; cout << "Employee ID: " << id << "\n"; } // Waiter methods void Waiter::set() { Worker::set(); cout << "Enter waiter's panache rating: "; cin >> panache; while (cin.get() != '\n') continue; } void Waiter::show() const { cout << "Category: waiter\n"; data(); } // protected method void Waiter::data() const { Worker::data(); cout << "Panache rating: " << panache << "\n"; } // SingingWaiter methods char * SingingWaiter::pv[] = {"other", "alto", "contralto", "soprano", "bass", "baritone", "tenor"}; void SingingWaiter::set() { Waiter::set(); cout << "Enter number for singer's vocal range:\n"; for (int i = 0; i < Vtypes; i++) { cout << i << ": " << pv[i] << " "; if ( i % 4 == 3) cout << '\n'; } if (i % 4 != 0) cout << '\n'; cin >> voice; while (cin.get() != '\n') continue; } void SingingWaiter::show() const { cout << "Category: singing waiter\n"; data(); } // protected method void SingingWaiter::data() const { Waiter::data(); cout << "Vocal range: " << pv[voice] << "\n"; } // workarr.cpp -- array of workers // compile with worker.cpp #include <iostream.h> #include <string.h> #include "worker.h" #include "arraytp.h" // omit if templates not implemented const int SIZE = 5; int main(void) { ArrayTP lolas; // if no templates, omit the above line and use the one below // Worker * lolas[SIZE]; for (int ct = 0; ct < SIZE; ct++) { char choice; cout << "Enter the employee category:\n" << "e: worker w: waiter s: singing waiter " << "q: quit\n"; cin >> choice; while (strchr("ewsq", choice) == NULL) { cout << "Please enter an e, w, s, or q: "; cin >> choice; } if (choice == 'q') break; switch(choice) { case 'e': lolas[ct] = new Worker; break; case 'w': lolas[ct] = new Waiter; break; case 's': lolas[ct] = new SingingWaiter; break; } cin.get(); lolas[ct]->set(); } cout << "\nHere is your staff:\n"; for (int i = 0; i < ct; i++) { cout << '\n'; lolas[i]->show(); } for (i = 0; i < ct; i++) delete lolas[i]; return 0; } // pairs.cpp -- define and use a Pair template #include <iostream.h> template class Pair { private: T1 a; T2 b; public: T1 & first(const T1 & f); T2 & second(const T2 & s); T1 first() const { return a; } T2 second() const { return b; } Pair(const T1 & f, const T2 & s) : a(f), b(s) { } }; template T1 & Pair ::first(const T1 & f) { a = f; return a; } template T2 & Pair ::second(const T2 & s) { b = s; return b; } int main(void) { Pair ratings[4] = { Pair ("The Purple Duke", 5), Pair ("Jake's Frisco Cafe", 4), Pair ("Mont Souffle", 5), Pair ("Gertie's Eats", 3) }; int joints = sizeof(ratings) / sizeof (Pair ); cout << "Rating:\t Eatery\n"; for (int i = 0; i < joints; i++) cout << ratings[i].second() << ":\t " << ratings[i].first() << "\n"; ratings[3].second(6); cout << "Oops! Revised rating:\n"; cout << ratings[3].second() << ":\t " << ratings[3].first() << "\n"; return 0; }
// workerfd.h -- working classes, first draft
#include "strng2.h"
class Worker
{
private:
String fullname;
long id;
protected:
virtual void data() const;
public:
Worker() : fullname("no one"), id(0L) {}
Worker(const String & s, long n)
: fullname(s), id(n) {}
virtual void set();
virtual void show() const;
};
class Waiter : public Worker
{
private:
int panache;
protected:
void data() const;
public:
Waiter() : Worker(), panache(0) {}
Waiter(const String & s, long n, int p = 0)
: Worker(s, n), panache(p) {}
Waiter(const Worker & wk, int p = 0)
: Worker(wk), panache(p) {}
void set();
void show() const;
};
class Singer : public Worker
{
public:
enum {Vtypes = 7};
protected:
enum {other, alto, contralto, soprano,
bass, baritone, tenor};
private:
static char *pv[Vtypes]; // string equivs of voice types
int voice;
protected:
void data() const;
public:
Singer() : Worker(), voice(other) {}
Singer(const String & s, long n, int v = other)
: Worker(s, n), voice(v) {}
Singer(const Worker & wk, int v = other)
: Worker(wk), voice(v) {}
void set();
void show() const;
};
// workermi.h -- working classes
#include "strng2.h"
class Worker
{
private:
String fullname;
long id;
protected:
virtual void data() const;
virtual void get();
public:
Worker() : fullname("no one"), id(0L) {}
Worker(const String & s, long n)
: fullname(s), id(n) {}
virtual void set();
virtual void show() const;
};
class Waiter : virtual public Worker
{
private:
int panache;
protected:
void data() const;
void get();
public:
Waiter() : Worker(), panache(0) {}
Waiter(const String & s, long n, int p = 0)
: Worker(s, n), panache(p) {}
Waiter(const Worker & wk, int p = 0)
: Worker(wk), panache(p) {}
void set();
void show() const;
};
class Singer : virtual public Worker
{
protected:
enum {other, alto, contralto, soprano,
bass, baritone, tenor};
enum {Vtypes = 7};
void data() const;
void get();
private:
static char *pv[Vtypes]; // string equivs of voice types
int voice;
public:
Singer() : Worker(), voice(other) {}
Singer(const String & s, long n, int v = other)
: Worker(s, n), voice(v) {}
Singer(const Worker & wk, int v = other)
: Worker(wk), voice(v) {}
void set();
void show() const;
};
class SingingWaiter : public Singer, public Waiter
{
protected:
void data() const;
void get();
public:
SingingWaiter() {}
SingingWaiter(const String & s, long n, int p = 0,
int v = Singer::other)
: Worker(s,n), Waiter(s, n, p), Singer(s, n, v) {}
SingingWaiter(const Worker & wk, int p = 0, int v = Singer::other)
: Worker(wk), Waiter(wk,p), Singer(wk,v) {}
SingingWaiter(const Waiter & wt, int v = other)
: Worker(wt),Waiter(wt), Singer(wt,v) {}
SingingWaiter(const Singer & wt, int p = 0)
: Worker(wt),Waiter(wt,p), Singer(wt) {}
void set();
void show() const;
};
// workermi.cpp -- working class methods
#include "workermi.h"
#include <iostream.h>
// Worker methods
void Worker::set()
{
cout << "Enter worker's name: ";
get();
}
void Worker::show() const
{
cout << "Category: worker\n";
data();
}
// protected methods
void Worker::data() const
{
cout << "Name: " << fullname << "\n";
cout << "Employee ID: " << id << "\n";
}
void Worker::get()
{
cin >> fullname;
cout << "Enter worker's ID: ";
cin >> id;
while (cin.get() != '\n')
continue;
}
// Waiter methods
void Waiter::set()
{
cout << "Enter waiter's name: ";
Worker::get();
get();
}
void Waiter::show() const
{
cout << "Category: waiter\n";
Worker::data();
data();
}
// protected methods
void Waiter::data() const
{
cout << "Panache rating: " << panache << "\n";
}
void Waiter::get()
{
cout << "Enter waiter's panache rating: ";
cin >> panache;
while (cin.get() != '\n')
continue;
}
// Singer methods
char * Singer::pv[Singer::Vtypes] = {"other", "alto", "contralto",
"soprano", "bass", "baritone", "tenor"};
void Singer::set()
{
cout << "Enter singer's name: ";
Worker::get();
get();
}
void Singer::show() const
{
cout << "Category: singer\n";
Worker::data();
data();
}
// protected methods
void Singer::data() const
{
cout << "Vocal range: " << pv[voice] << "\n";
}
void Singer::get()
{
cout << "Enter number for singer's vocal range:\n";
for (int i = 0; i < Vtypes; i++)
{
cout << i << ": " << pv[i] << " ";
if ( i % 4 == 3)
cout << '\n';
}
if (i % 4 != 0)
cout << '\n';
cin >> voice;
while (cin.get() != '\n')
continue;
}
// SingingWaiter methods
void SingingWaiter::data() const
{
Singer::data();
Waiter::data();
}
void SingingWaiter::get()
{
Waiter::get();
Singer::get();
}
void SingingWaiter::set()
{
cout << "Enter singing waiter's name: ";
Worker::get();
get();
}
void SingingWaiter::show() const
{
cout << "Category: singing waiter\n";
Worker::data();
data();
}
// workmi.cpp -- multiple inheritance
// compile with workermi.cpp, strng2.cpp
#include <iostream.h>
#include <string.h>
#include "workermi.h"
#include "arraytp.h" // omit if no template support
const int SIZE = 5;
int main(void)
{
ArrayTP lolas;
// if no template support, omit the above and use the following:
// Worker * lolas[SIZE];
for (int ct = 0; ct < SIZE; ct++)
{
char choice;
cout << "Enter the employee category:\n"
<< "e: worker w: waiter s: singer "
<< "t: singing waiter q: quit\n";
cin >> choice;
while (strchr("ewstq", choice) == NULL)
{
cout << "Please enter an e, w, s, t, or q: ";
cin >> choice;
}
if (choice == 'q')
break;
switch(choice)
{
case 'e': lolas[ct] = new Worker;
break;
case 'w': lolas[ct] = new Waiter;
break;
case 's': lolas[ct] = new Singer;
break;
case 't': lolas[ct] = new SingingWaiter;
break;
}
cin.get();
lolas[ct]->set();
}
cout << "\nHere is your staff:\n";
for (int i = 0; i < ct; i++)
{
cout << '\n';
lolas[i]->show();
}
for (i = 0; i < ct; i++)
delete lolas[i];
return 0;
}