Tom Kelliher, CS23
Mar. 27, 1996
Terminology:
Checking account +.
Elements:
/********************************************************************** * checking.h --- Class declaration for a simple checking account. * Tom Kelliher * * A Checking object consists of an account number and balance. * Allowed operations: * Constructor: Create a checking account with a given account * number and balance. * inputTrans: Apply a transaction (from enum TransactionType) to * the account. * printBalance: Print the account number and balance. * printEverything: print all information associated with an * account. * * This class is a base class for a joint checking class. **********************************************************************/ #ifndef __CHECKING_H #define __CHECKING_H // Types of allowed transaction. enum TransactionType { DEPOSIT = 'D', WITHDRAWAL = 'W' }; class Checking { private: int accntNumber; double accntBalance; public: Checking(int number, double balance); void inputTrans(TransactionType type, double amount); void printBalance(void); void printEverything(void); }; #endif
#include <iostream.h> #include <iomanip.h> #include "checking.h" // These methods are documented in checking.h /********************************************************************** * Checking::Checking **********************************************************************/ Checking::Checking(int number, double balance) : accntNumber(number), accntBalance(balance) { } /********************************************************************** * Checking::inputTrans **********************************************************************/ void Checking::inputTrans(TransactionType type, double amount) { switch (type) { case DEPOSIT: accntBalance += amount; break; case WITHDRAWAL: accntBalance -= amount; break; default: cout << "Illegal transaction code: " << char(type) << endl; break; } } /********************************************************************** * Checking::printBalance **********************************************************************/ void Checking::printBalance(void) { // This method twiddles with output formatting. We need to save // the output formatting and then restore it before returning. long oldPrecision; long oldFixed; cout << "The balance for account " << accntNumber << " is "; // Save previous formatting. oldPrecision = cout.precision(2); oldFixed = cout.setf(ios::fixed, ios::floatfield); cout << accntBalance << ".\n"; // Restore previous formatting. cout.precision(oldPrecision); cout.setf(oldFixed, ios::floatfield); } /********************************************************************** * checking::printEverything --- just call printBalance which, for * this class, prints everything. **********************************************************************/ void Checking::printEverything(void) { printBalance(); }
/********************************************************************** * joint.h --- Class declaration for a simple joint checking account. * Tom Kelliher * * A Joint object consists of a Checking base class with appendant * owner and joint owner SSNs. * Allowed operations: * Constructor: Create a joint checking account with owner and * joint owner SSNs, an account number, and an account balance. * printSsn: Print the SSNs of the two owner. * printEverything: print all information associated with the * account. * * Public inheritance of the Checking class is used, so see checking.h * for other allowed operations. **********************************************************************/ #ifndef __JOINT_H #define __JOINT_H // Read header file for base class. #include "checking.h" class Joint : public Checking // Checking is inherited with public // access. { private: long ownerSsn; long jointOwnerSsn; public: Joint(long oSsn, long jSsn, int number, double balance); void printSsn(void); void printEverything(void); // Static override of //Checking::printEverything }; #endif
#include <iostream.h> #include "joint.h" // These methods are documented in joint.h /********************************************************************** * Joint::Joint **********************************************************************/ Joint::Joint(long oSsn, long jSsn, int number, double balance) : Checking(number, balance), // Invoke constructor for base class. ownerSsn(oSsn), jointOwnerSsn(jSsn) { } /********************************************************************** * Joint::printSsn **********************************************************************/ void Joint::printSsn(void) { cout << "Owner SSN: " << ownerSsn << endl; cout << "Joint SSN: " << jointOwnerSsn << endl; } /********************************************************************** * Joint::printEverything --- Prints all information associated with * the account. **********************************************************************/ void Joint::printEverything() { printSsn(); Checking::printEverything(); // Why not just printEverything()? }
#include <iostream.h> #include "checking.h" #include "joint.h" int main() { Checking check(569248, 1000.00); Joint joint(111223333, 444556666, 987234, 500.00); check.inputTrans(DEPOSIT, 100.00); check.printBalance(); check.inputTrans(WITHDRAWAL, 50.00); check.printBalance(); cout << endl; joint.printSsn(); joint.inputTrans(DEPOSIT, 39.00); joint.printBalance(); cout << endl; check.printEverything(); // Static binding. cout << endl; joint.printEverything(); // Static binding. return 0; }
Consider a linked list of checking accounts:
... List<Checking> accounts; accounts.insert(new Checking(...)); accounts.insert(new Joint(...)); accounts.display(); ... template <class T> void List<T>::display(void) { listnode<T>* tmp = head; while (tmp != NULL) { tmp->printEverything(); // Pointing to Checking or Joint? cout << endl; } }
Which printEverything() should be called?
Cannot be determined until runtime.
Communicated to compiler by virtual attribute of
printEverything() in base class
( Checking).
A class with at least one pure virtual function, that is, a function which is not defined. Such a class cannot be instantiated.
Why allow such a thing?
Example:
#include <iostream.h> class twoInts { protected: int first; int second; public: twoInts(int a, int b) : first(a), second(b) {} virtual void display(void) = 0; // ... }; class rational : public twoInts { // ... public: rational(int a, int b) : twoInts(a, b) {} void display(void) { cout << first << "/" << second; } // ... }; int main() { rational rat = rational(1, 3); rat.display(); cout << endl; return 0; }