Hi guys this is the first time ive posted to this forum, and ive tried getting my answer by asking others and google, but what i'm after is to complete an assignment that is asking me to complete a program that basically works as an ATM machine. it reads in a customer file and using that data it will determine what customer has what account. The assignment has to include inheritance and four classes so what i have posted below doesnt work but it has the four classes. Also the program must have basic ATM functionality like being able to withdraw, deposit etc, but i can probably manage on my own. Any help would be appreciated or if you could steer me into the correct direction, i dont expect anything to give me the answers but any help would be greatly appreciated.


Customers.dat file:

Jason Santa
67 eighth Ave, heats
S
123456
0.00
X
Joseph jasons
20 Wattle Ave, Doonside
K
937568
0.00
S
246890
0.00
C
917355
0.00
X
James Bond
C/- MI6, London
C
293567
0.00
X
Napolean Solo
Delflorios, New York City
S
337761
0.00
C
846579
0.00
X

C++ code from before:

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;
const float savingsInterestRate =0.05;
const int maxCustomers = 7;
const int maxTrans = 20;
// Savings Account class
class savingsAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             savingsAccount(int,float,float);
             void setupAccount(int, float,float);
             void addDeposit(float amount);
             void subWdrawal(float amount);
             void addInterest();
             float getBalance();
             bool matchAccount(int);
};

bool savingsAccount::matchAccount(int accNo)
{
     if(accNo==accNumber) return true;
     else return false;
 }
// Constructor function
savingsAccount::savingsAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void savingsAccount::setupAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void savingsAccount::addDeposit(float amount)
{
     balance=balance+amount;

     }
void savingsAccount::subWdrawal(float amount)
{
     balance=balance-amount;

}
void savingsAccount::addInterest()
{
     balance=balance+balance*interestRate;
}
float savingsAccount::getBalance()
{
      return balance;
}
class checqueAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             checqueAccount(int,float,float);
             void setupAccount(int, float,float);
             void addDeposit(float amount);
             void subWdrawal(float amount);
             void addInterest();
             float getBalance();
             bool matchAccount(int);
};

bool checqueAccount::matchAccount(int accNo)
{
     if(accNo==accNumber) return true;
     else return false;
 }
// Constructor function
checqueAccount::checqueAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void checqueAccount::setupAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void checqueAccount::addDeposit(float amount)
{
     balance=balance+amount;

     }
void checqueAccount::subWdrawal(float amount)
{
     balance=balance-amount;

}
void checqueAccount::addInterest()
{
     balance=balance+balance*interestRate;
}
float checqueAccount::getBalance()
{
      return balance;
}
class creditAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             creditAccount(int,float,float);
             void setupAccount(int, float,float);
             void addDeposit(float amount);
             void subWdrawal(float amount);
             void addInterest();
             float getBalance();
             bool matchAccount(int);
};

bool creditAccount::matchAccount(int accNo)
{
     if(accNo==accNumber) return true;
     else return false;
 }
// Constructor function
creditAccount::creditAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void creditAccount::setupAccount(int aN, float bal,float iRate)
{
    accNumber=aN;
    balance=bal;
    interestRate=iRate;
}

void creditAccount::addDeposit(float amount)
{
     balance=balance+amount;

     }
void creditAccount::subWdrawal(float amount)
{
     balance=balance-amount;

}
void creditAccount::addInterest()
{
     balance=balance+balance*interestRate;
}
float creditAccount::getBalance()
{
      return balance;
}

//Customer class containing savingsAccount object
class Customer
{
      private:
              string name;
              string address;
              savingsAccount sAccnt;
      public:
             Customer(string = "", string ="", int =0, float =0.0, float =savingsInterestRate);
             void CreateCust(string, string, int);
             void accessAccount(char);
             bool searchAccounts(int);
             void applyTrans(char,float);
};
// This function could be put in the savingsAccount class (some other changes would be necessary)
void Customer::applyTrans(char transType, float amt)
{
  if(transType=='C') sAccnt.addDeposit(amt) ;
  else if(transType=='D') sAccnt.subWdrawal(amt) ;
       else sAccnt.addInterest();
}
//Constructor function calling savingsAccount constructor
Customer::Customer(string nme, string addr,int an, float b, float ir):sAccnt(an,b,ir)
{
   name = nme;
   address = addr;
}
void Customer::CreateCust(string nme, string addr, int saNumber)
{
  name = nme;
  address = addr;
  sAccnt.setupAccount(saNumber,0.0,savingsInterestRate); // call savingsAccount setup function
}

bool Customer::searchAccounts(int accNo)
{
   if (sAccnt.matchAccount(accNo)) return true;
   else return false;
}
// Access account to get balance
void Customer::accessAccount(char op)
{    float amt;
     cout<<fixed;
     if (op=='B') cout<<"Balance of "<<setw(10)<<name<<"s account is: "<<setw(10)<<setprecision(2)<<sAccnt.getBalance()<<endl;

}
// Transaction class - simple version, other functions in ProcessTrans class
class Transact
{
      private:
              int accNo;
              float amt;
              char transType;
      public:
             void readRecord(ifstream&);
             int getTransAccNo();
             float getTransAmt();
             char getCode();

};
// Read one transaction record from file
void Transact::readRecord(ifstream &infile)
{
   infile>>accNo;
   infile >> amt;
   infile>>transType;

}
int Transact::getTransAccNo()
{
  return accNo;
}

float Transact::getTransAmt()
{
  return amt;
}
char Transact::getCode()
{
  return transType;
}
//Process transactions class containing customers and transactions
class ProcessTrans
{
    private:
       Customer custs[maxCustomers];
       Transact trans[maxTrans];
       ifstream infile;
       int numTrans;                //Actual number of transactions read from file
                                    //could include number of customers if using file
       int findAcc(int);                             
    public:
        void getCustomers();
        void getTrans();
        void Process();
        void Report();
};

void ProcessTrans::getCustomers()           // Could read from a file
{
      custs[0].CreateCust("Mark","63 Ninth",123456);
      custs[1].CreateCust("Pam","20 Wattle",246890);
      custs[2].CreateCust("Bill","20 Wattle",917355);
      custs[3].CreateCust("Fred","20 Wattle",937568);
      custs[4].CreateCust("Keith","20 Wattle",337761);
      custs[5].CreateCust("Kevin","20 Wattle",846579);
      custs[6].CreateCust("Bron","20 Wattle",293567);
}
// Load tranactions into array from file
void ProcessTrans::getTrans()
{   int count=0;
    infile.open("trans.dat");
    if(infile.fail()) cout<<"File not found";
    else {
      while(infile.peek()!=EOF) {
       trans[count].readRecord(infile);
       count++;
      }
    }
    infile.close();
    numTrans=count-1;

}
void ProcessTrans::Report()
{
  for(int i=0;i<maxCustomers;i++)
    custs[i].accessAccount('B');
}
// Find the customer whose account matches the transaction account number
int ProcessTrans::findAcc( int accNo)
{
        for(int i=0;i<maxCustomers;i++)
         if (custs[i].searchAccounts(accNo))   return i;
        return -1;
}
// Main processing driver function
void ProcessTrans::Process()
{    int cust,i;
     for(i=0;i<numTrans;i++) {                   // Loop through transaction array
       cust = findAcc(trans[i].getTransAccNo()); // find customer for that transaction
       if (cust>=0)
         custs[cust].applyTrans(trans[i].getCode(),trans[i].getTransAmt()); // apply the transaction
       else cout<<"No customer found";
     }
}

int main(){
 ProcessTrans pt;
 pt.getCustomers();
 cout<<"sim08u's Bank"<<endl;
 cout<<"Transaction Daily Report"<<endl;
 cout<<"========================"<<endl;
 cout<<"Initial Balances"<<endl;
 cout<<"----------------"<<endl;
 pt.Report();
 pt.getTrans();
 cout<<endl<<"Processing Transactions"<<endl<<endl;
 pt.Process();
 cout<<"Final Balances"<<endl;
 cout<<"--------------"<<endl;
 pt.Report();
 system("pause");
 return 0;
}

Recommended Answers

All 12 Replies

Since your savings-account, checking-account, and credit-account classes are identical (or nearly so), consider starting with a base class:

class GenericAccount
{
    /* mostly the same stuff you already have */
    GenericAccount(int accountNum, float balance, float interestRate);
};

and then inherit it, overriding any methods that need to change, or adding new ones:

class SavingsAccount(public GenericAccount)
{
    SavingsAccount(int accountNum, float balance, float interestRate):
      GenericAccount(accountNum, balance, interestRate)
    {
        /* anything extra you need to do, possibly nothing */
    }

    /* add or replace anything that's particular to a SavingsAccount */
};

You might want to make Customer.sAccount a pointer (and so on for chAccount, crAccount) so that they can be NULL if the customer doesn't have that kind of account, until he adds such an account. Though adding accounts isn't functionality usually found in an ATM! :)

As far as your code not working, what does it do? What does it -not- do? Does your program crash and if so what error message do you get?

hi thanks for the quick reply, as of now the program i gave to you was given to us by my tutor and all i did was add new classes so at the moment it doesnt do anything but apply transactions from a trans.dat file. now what i want to do is get rid of this functionality and add the ability to read in the accounts from the customers file and basic atm functionality if ya know what i mean.

OK. I think I know what you mean, but since I don't know what code you got from your tutor, and what of the code you've added to, I'm not sure where you're stuck in doing what you need.

I see a Transact::readRecord() method. You could use something very similar to that to create a Customer::readCustomer() method, which would populate your Customer class. From the data file, it looks like account-types are K, S or C, or if you read an X then you're done with that customer and go on to the next one.

Write just enough code to do that, and test it. Then think about what you need to do next. Reading input from the user is as simple as replacing "infile >>" with "std::cin >>" for the interactive ATM functionality.

ok im just gonna start again and i'll post back when i get stuck again, if thats ok with you? im not very good at c++ but ill try...lol

would it perhaps be easier for me to show you the actual assignment sheet? im sort of running through this bit by bit but maybe u can gain a greater understanding of what im trying to do if u look at the assignment sheet. I'll try and attatch it for you. thanks you so much for this :)

Interesting. Among other things, your assignment sheet specifically instructs you to do what I suggested: start with a GenericAccount class and derive the other accounts from that. The assignment is so specific and detailed, you should probably consider following it, step by step, and then post back here when you can't get a step to work the way you want.

ok ive finished my part i got something like 30 errors unfortunately here it is.

i honestly have no idea how to implement the other parts of the assignment.

To start, you aren't really clear on class inheritance. For example, you have:

class bankAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             void deposit(float amount);
             void withdraw(float amount);
             void displayAccount(int, float);
             void setupAccount(int, float, float);
             bool matchAccount(int);
             float getBalance();
};

...

class savingsAccount : public bankAccount
{
      private:
              int accNumber;
              float balance;
              float interestRate;
      public:
             void calculateInterest(float, float);
             savingsAccount (int, float, float);
};

Members of a class which are safe to be inherited by derived classes should be "protected:" instead of "private:". The "private:" designation is probably rarely needed and is only relevant for portions of a parent class which, for whatever reason, should not or cannot be inherited by derived classes.

So if you make accNumber and balance "protected:" in bankAccount, you then get them for free in savingsAccount, which is part of the point.

Then your assignment specifically states:
"The generic bank account should contain an account number and balance data
members but no interest rate."
So I wonder why you have an interestRate member in your bankAccount class.

Your bankAccount class has no bankAccount() constructor. Instead it has a setupAccount() method which does the same thing. Resolve this by renaming setupAccount() to bankAccount(). Given that it shouldn't have an interest rate, do not provide or assign one in your constructor.

Then, also following the notion of inheritance, the constructor of your derived class should call the constructor of the base class, to avoid duplicating the same work (even though in your case, it's just trivial assignments):

savingsAccount::savingsAccount(int aN, float bal, float iRate):
    bankAccount(aN, bal)
{
    interestRate=iRate;
}

Also, you waste a lot of space respecifying method bodies which haven't changed. They're already declared as "public:" in the base class, so again, you get them for free. E.g.:

void bankAccount::deposit(float amount)
{
     balance=balance+amount;
}

...

void savingsAccount::deposit(float amount)
{
     balance=balance+amount;
}

although if you -do- need to override a method in a derived class, then you need to re-specify its prototype in the class definition!

So altogether, the only methods you need to specify for the derived class are (1) any -new- methods, such as the constructor, and in the case of the savingsAccount class, the calculateInterest() method, and (2) any methods that need to behave differently because of the specifics of the derived class -- in particular, re-read the part of the assignment that discusses the credit-card account and how the deposit() and withdrawal() methods should behave, you have them incorrect in your code.

Your bankAccount class specifies a displayAccount() method prototype which you haven't implemented.

You have a typo at your current line 237 which is probably causing you a bunch of headaches.

Finally (I'm not going to read any further this evening), your setup for the Customer class in general is broken.

First of all, you have default values in your constructor for almost every possible field, which in your case probably doesn't make sense: a customer will always have a name and address. Also, I'm reasonably sure that any parameters (to any method or function) which require a value must come first, and any that don't should follow, so that the compiler can figure out what values to assign to which parameters. You may also have to provide dummy parameter names in your prototype, if you're going to provide default values, e.g.

Customer(string, string, char, int acctNo=0, float bal=0.0);

Then you provide three implementations of your constructor, none of which takes the same parameters you specify in your one prototype. I think what you're trying to specify is something like:

Customer::Customer(string nme, string addr):
    sAccnt(0, 0.0, 0.0), cAccnt(0, 0.0, 0.0), ccAccnt(0, 0.0, 0.0)
{
    name = nme;
    address = addr;
}

where you can use an accountNum of zero to indicate that the customer does not have an account of that type, until one is assigned. Otherwise, you will need other members (perhaps bools?) to indicate whether the customer has an account of each type.

The good news is: this means each account type needs an inherited or overridden setupAccount() to provide the actual info once you have it. Or you can use pointers to these account-types and instantiate them as needed:

class Customer
{
      private:
              string name;
              string address;
              savingsAccount *sAccnt;
              checqueAccount *cAccnt;
              creditAccount *ccAccmt;
      public:
             Customer(string, string);
             void addSavingsAccount(int, float, float);
             ...
};

Customer::Customer(string nme, string addr):
    sAccnt(NULL), cAccnt(NULL), ccAccnt(NULL)
{
    name = nme;
    address = addr;
}

void Customer::addSavingsAccount(int acctNo, float bal, float iRate)
{
    sAccnt = new savingsAccount(acctNo, bal, iRate);
}

...

I can't recommend enough doing this step by step, putting things in separate files (and #include'ing what you need), and testing the parts as you go.

As far as having "no idea how to implement the other parts," get as far as you can, and get that much working and tested. Then we can talk more about where you're stuck.

For a little bit of sanity, I'm including a small amount of code which I've verified compiles, and am reasonably certain will work. If you would like to use it, feel free, but -you- are responsible for testing it.

#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;

// generic class for a Bank Account

class BankAccount
{
    protected:
        int accNumber;
        float balance;

    public:
        BankAccount(int acctNo, float bal=0.0);
        bool matchesAccountNum(int acctNo);
        float getBalance();
        void deposit(float amount);
        void withdraw(float amount);
        void display();
};

BankAccount::BankAccount(int acctNo, float bal):
    accNumber(acctNo), balance(bal)
{
}

bool BankAccount::matchesAccountNum(int acctNo)
{
    return (accNumber == acctNo);
}

float BankAccount::getBalance()
{
    return balance;
}

void BankAccount::deposit(float amount)
{
    balance = balance + amount;
}

void BankAccount::withdraw(float amount)
{
    // fix this: read your assignment sheet, it tells you exactly how this
    // should behave!
    balance = balance - amount;
}

void BankAccount::display()
{
    printf("Generic Bank Account\n");
    printf("  account number: %d\n", accNumber);
    printf("  balance:        $%.2f\n", balance);
}


// derived Savings Account class

class SavingsAccount : public BankAccount
{
    protected:
        // inherits accNumber and balance from BankAccount
        float interestRate;

    public:
        // inherits matchesAccountNum(), getBalance(), deposit() as-is from
        // BankAccount
        SavingsAccount(int acctNo, float bal=0.0, float iRate=0.0);
        void applyInterest(float fractionOfYear);
        // overridden methods from BankAccount
        void withdraw(float amount);
        void display();
};

SavingsAccount::SavingsAccount(int acctNo, float bal, float iRate):
    BankAccount(acctNo, bal), interestRate(iRate)
{
}

void SavingsAccount::applyInterest(float fractionOfYear)
{
    balance = balance + balance*(interestRate * fractionOfYear);
}

// override these inherited methods

void SavingsAccount::withdraw(float amount)
{
    if (amount > balance) {
        // can't overdraw your SavingsAccount, do something else here
        // (hint: read your assignment sheet)
    }
    else
        balance = balance - amount;
}

void SavingsAccount::display()
{
    printf("Savings Account\n");
    printf("  account number:       %d\n", accNumber);
    printf("  annual interest rate: %%%.1f\n", interestRate*100);
    printf("  balance:              $%.2f\n", balance);
}

your code doesnt compile.

I like your code, raptr_dflo, buh why not make use of cout instead of printf()?

your code doesnt compile.

Compiles fine for me, I made sure of it before I attached it. Which I made a point of saying.
g++ -c -g bankAccount.cpp

It doesn't link into an executable because it doesn't have a main() (or much of anything else that makes a complete program), it's a usable example of how to derive a subclass.

I like your code, raptr_dflo, buh why not make use of cout instead of printf()?

Thanks tkud! And to answer your question: no good reason, they both work just fine. :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.