JMU
Classes and Objects in C++: Some Advanced Topics
for Java Programmers


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Polymorphism
Polymorphism (cont.)
Virtual Methods
An Example

The Specification of Account

cppexamples/oopbasics/banking/Account.h
        #ifndef edu_jmu_cs_Account_h
#define edu_jmu_cs_Account_h

/**
 * A simple "bank" Account
 *
 * @author  Prof. David Bernstein, James Madison University
 */
class Account {
 private:
  float balance;
  int id;

 public:
  /**
   * Explicit Value Constructor
   *
   * @param id              The ID number for this account
   * @param initialDeposit  The initial deposit (in dollars)
   */
  Account(int id, float initialDeposit);

  /**
   * Destructor.
   */
  virtual ~Account();

  /**
   * Determines the maximum amount that can be withdrawn
   *
   * @return  The size of the maximum possible withdrawal
   */
  virtual double amountAvailable(void);

  /**
   * Deposits money in this Account
   *
   * @param amount   The size of the deposit
   * @return         0 if unable to make the deposit and 1 otherwise
   */
  int deposit(float amount);

  /**
   * Gets the ID of this Account
   *
   * @return   The ID
   */
  int getID(void);

  /**
   * Withdraw money from this Account
   *
   * @param amount  The size of the withdrawal
   * @return        0 if unable to make the withdrawal and 1 otherwise
   */
  int withdraw(float amount);
};

#endif
        
An Example (cont.)

The Implementation of Account

cppexamples/oopbasics/banking/Account.cpp
        #include "Account.h"

Account::Account(int idNumber, float initialDeposit) {
  balance = 0;

  id = idNumber;
  if (initialDeposit > 0)
    balance = initialDeposit;
}

double Account::amountAvailable(void) {
  return balance;
}

int Account::deposit(float amount) {
  // Error checking
  if (amount < 0)
    return 0;

  balance += amount;
  return 1;
}

int Account::getID(void) {
  return id;
}

int Account::withdraw(float amount) {
  // Error checking
  if (amount < 0)
    return 0;

  // Check if available funds are sufficient
  if (amountAvailable() < amount)
    return 0;

  balance -= amount;
  return 1;
}
        
An Example (cont.)

The Specification of an Overdraft Account

cppexamples/oopbasics/banking/OverdraftAccount.h
        #ifndef edu_jmu_cs_OverdraftAccount_h
#define edu_jmu_cs_OverdraftAccount_h

#include "Account.h"

/**
 * A "bank" Account that allows the owner to withdraw more money
 * than is in the account 
 *
 * @author  Prof. David Bernstein, James Madison University
 */
class OverdraftAccount : public Account {
 public:
  /**
   * Explicit Value Constructor
   *
   * @param idNumber        The ID for the Account
   * @param initialDeposit  The initial deposit
   * @param limit           The overdraft limit
   */
  OverdraftAccount(int idNumber, double initialDeposit, double limit);

  /**
   * Determine the maximum amount that can be withdrawn
   *
   * Note: This method overrides amountAvailable() in Account.
   * This method is called by the method withdraw() which
   * is defined in Account.
   *
   * @return The size of the maximum possible withdrawal
   */
  double amountAvailable();

 protected:
  double overdraftLimit;
};

#endif
        
An Example (cont.)

The Implementation of an Overdraft Account

cppexamples/oopbasics/banking/OverdraftAccount.cpp
        #include "OverdraftAccount.h"

OverdraftAccount::OverdraftAccount(int idNumber, double initialDeposit,
                                   double limit)
    : Account(idNumber, initialDeposit) {
  overdraftLimit = 0.0;
  if (limit > 0.0)
    overdraftLimit = limit;
}

double OverdraftAccount::amountAvailable() {
  return (Account::amountAvailable() + overdraftLimit);
}
        
An Example (cont.)

A Driver

First, build and execute the application with the amountAvailable() method declared virtual. Then, build and execute the application without the amountAvailable() method declared virtual. Which behaves like Java?

cppexamples/oopbasics/banking/Driver.cpp
        #include "Account.h"
#include "OverdraftAccount.h"

#include <iostream>
using namespace std;

/**
 * \file
 * An example that uses the Account and OverdraftAccount classes
 *
 * @author  Prof. David Bernstein, James Madison University
 */

/**
 * A function to illustrate what happens when an
 * OverdraftAccount is passed as an Account
 */
void print(Account *a) {
  cout << a->getID() << " available: " << a->amountAvailable() << "\n";

}

/**
 * The entry point of the application
 */
int main(void) {
  int ok;

  Account *andrew;
  Account *orville;
  OverdraftAccount *ollie;

  andrew = new Account(1001, 100.00);
  orville = new OverdraftAccount(1002, 100.0, 200.0);
  ollie = new OverdraftAccount(1003, 100.0, 200.0);

  cout << "\nUsing objects directly:\n";
  cout << andrew->getID() << " available: " << andrew->amountAvailable()
       << "\n";
  cout << orville->getID() << " available: " << orville->amountAvailable()
       << "\n";
  cout << ollie->getID() << " available: " << ollie->amountAvailable() << "\n";

  cout << "\nUsing objects passed as Account objects:\n";
  print(andrew);
  print(orville);
  print(ollie);

  return 1;
}
        
Pure Virtual Methods
Pure Virtual Methods (cont.)
Behavior of Destructors
  1. The destructor in the derived class is executed
  2. The base class destructor is executed
  3. The memory allocated to the object is returned to the free store
Run-Time Type Identification (RTTI)