3 Replies - 649 Views - Last Post: 28 January 2013 - 02:01 PM Rate Topic: -----

#1 AnalyticLunatic  Icon User is offline

  • D.I.C Lover

Reputation: 223
  • View blog
  • Posts: 1,035
  • Joined: 25-June 12

(Inheritance) No Runtime Error, but Incorrect Output

Posted 25 January 2013 - 02:48 PM

Hello, hopefully someone more familiar with C++ can assist me. I have composed this program to practice with class inheritance. Everything is now running correctly and no errors are flagging, however as can be seen in my attached image, something is going horribly wrong while adding charges for crediting an Account.

Can anyone tell me what I am doing wrong?

Posted Image

Account.h
// Definition of Account class.
#ifndef ACCOUNT_H
#define ACCOUNT_H

class Account
{
public:
   Account(){};

   Account( double balance); // constructor initializes balance
   void credit( double ); // add an amount to the account balance
   bool debit( double ); // subtract an amount from the account balance
   void setBalance( double ); // sets the account balance
   double getBalance(); // return the account balance
private:
   double balance; // data member that stores the balance
}; // end class Account

#endif



CheckingAccount.h
// Definition of CheckingAccount class.
#ifndef CHECKING_H
#define CHECKING_H

/* Write a directive to include the Account header file */
#include "Account.h"
/* Write a line to have class CheckingAccount inherit publicly from Account */
class CheckingAccount : public Account
{
public:
   // constructor initializes balance and transaction fee
   /* Declare a two-argument constructor for CheckingAccount */
	CheckingAccount(double, double fee);
   /* Redeclare member function credit, which will be redefined */
	void credit( double);
   /* Redeclare member function debit, which will be redefined */
	void debit( double);
private:
   /* Declare data member transactionFee */
	double transactionFee;
   // utility function to charge fee
   /* Declare member function chargeFee */
	void chargeFee();
}; // end class CheckingAccount

#endif



SavingsAccount.h
#ifndef SAVINGS_H
#define SAVINGS_H
#include "Account.h"
class SavingsAccount : public  Account
{
public:
   // constructor initializes balance and interest rate
	SavingsAccount(double balance, double intRate);
	double calculateInterest(double, double);
private:
	double interestRate;
}; // end class SavingsAccount

#endif



Account.cpp
// Member-function definitions for class Account.
#include <iostream>
using namespace std;

#include "Account.h" // include definition of class Account

// Account constructor initializes data member balance
Account::Account( double initialBalance )
{
   // if initialBalance is greater than or equal to 0.0, set this value 
   // as the balance of the Account
   if ( initialBalance >= 0.0 )
      balance = initialBalance;
   else // otherwise, output message and set balance to 0.0
   {
      cout << "Error: Initial balance cannot be negative." << endl;
      balance = 0.0;
   } // end if...else
} // end Account constructor

// credit (add) an amount to the account balance
void Account::credit( double amount )
{
   balance = balance + amount; // add amount to balance
} // end function credit

// debit (subtract) an amount from the account balance
// return bool indicating whether money was debited
bool Account::debit( double amount )
{
   if ( amount > balance ) // debit amount exceeds balance
   {
      cout << "Debit amount exceeded account balance." << endl;
      return false;
   } // end if
   else // debit amount does not exceed balance
   {
      balance = balance - amount;
      return true;
   } // end else
} // end function debit

// set the account balance
void Account::setBalance( double newBalance )
{
   balance = newBalance;
} // end function setBalance

// return the account balance
double Account::getBalance()
{
   return balance;
} // end function getBalance



CheckingAccount.cpp
// Member-function definitions for class CheckingAccount.
#include <iostream>
using namespace std;

#include "CheckingAccount.h" // CheckingAccount class definition

// constructor initializes balance and transaction fee
CheckingAccount::CheckingAccount(double initialBalance, double transactionFee)
	:Account(transactionFee) {}

// credit (add) an amount to the account balance and charge fee
void CheckingAccount::credit(double money)
{
	Account::setBalance(Account::getBalance() + money);
	chargeFee();
}

// debit (subtract) an amount from the account balance and charge fee
void CheckingAccount::debit(double money)
{
	if (Account::debit(money))
	{
		Account::setBalance(Account::getBalance() - money);
		chargeFee();
	}
}

// subtract transaction fee
void CheckingAccount::chargeFee()
{
	Account::setBalance(Account::getBalance() - transactionFee);
	cout<<"\n"<<" Charged a fee of "<< transactionFee;
}



SavingsAccount.cpp
// Member-function definitions for class SavingsAccount.

#include "SavingsAccount.h" // SavingsAccount class definition

// constructor initializes balance and interest rate
SavingsAccount::SavingsAccount(double initialBalance, double interestRate)
	:Account(interestRate) {}

// return the amount of interest earned
double SavingsAccount::calculateInterest(double balance, double interestRate)
{
	return balance*interestRate;
}



bankAccounts.cpp (The Driver)
#include <iostream>
#include <iomanip>
using namespace std;

#include "Account.h" // Account class definition
#include "SavingsAccount.h" // SavingsAccount class definition
#include "CheckingAccount.h" // CheckingAccount class definition

int main()
{
   Account account1( 50.0 ); // create Account object
   SavingsAccount account2( 25.0, .03 ); // create SavingsAccount object
   CheckingAccount account3( 80.0, 1.0 ); // create CheckingAccount object
   
   cout << fixed << setprecision( 2 );

   // display initial balance of each object
   cout << "account1 balance: $" << account1.getBalance() << endl;
   cout << "account2 balance: $" << account2.getBalance() << endl;
   cout << "account3 balance: $" << account3.getBalance() << endl;

   cout << "\nAttempting to debit $25.00 from account1." << endl;
   account1.debit( 25.0 ); // try to debit $25.00 from account1
   cout << "\nAttempting to debit $30.00 from account2." << endl;
   account2.debit( 30.0 ); // try to debit $30.00 from account2
   cout << "\nAttempting to debit $40.00 from account3." << endl;
   account3.debit( 40.0 ); // try to debit $40.00 from account3
   
   // display balances
   cout << "\naccount1 balance: $" << account1.getBalance() << endl;
   cout << "account2 balance: $" << account2.getBalance() << endl;
   cout << "account3 balance: $" << account3.getBalance() << endl;

   cout << "\nCrediting $40.00 to account1." << endl;
   account1.credit( 40.0 ); // credit $40.00 to account1
   cout << "\nCrediting $65.00 to account2." << endl;
   account2.credit( 65.0 ); // credit $65.00 to account2
   cout << "\nCrediting $20.00 to account3." << endl;
   account3.credit( 20.0 ); // credit $20.00 to account3

   // display balances
   cout << "\naccount1 balance: $" << account1.getBalance() << endl;
   cout << "account2 balance: $" << account2.getBalance() << endl;
   cout << "account3 balance: $" << account3.getBalance() << endl;

   // add interest to SavingsAccount object account2
   //double interestEarned = account2.calculateInterest( account2.getBalance() , interestEarned);
   double interestEarned = account2.calculateInterest( account2.getBalance() , 0.10);
   cout << "\nAdding $" << interestEarned << " interest to account2." 
      << endl;

   account2.setBalance(account2.getBalance() + interestEarned);

   cout << "\nNew account2 balance: $" << account2.getBalance() << endl;


   system("pause");
   return 0;
} // end main



Is This A Good Question/Topic? 0
  • +

Replies To: (Inheritance) No Runtime Error, but Incorrect Output

#2 NathanMullenax  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 86
  • View blog
  • Posts: 189
  • Joined: 23-September 12

Re: (Inheritance) No Runtime Error, but Incorrect Output

Posted 25 January 2013 - 02:58 PM

It looks like your constructor for CheckingAccount is leaving something uninitialized. It invokes the super-constructor in its initializer, but passes it transactionFee instead of initialBalance (which is what Account expects). TransactionFee isn't set anywhere, and accordingly is initially some random uninitialized value, which is why you are getting such a weird number after a fee has been assessed.
Was This Post Helpful? 1
  • +
  • -

#3 jimblumberg  Icon User is offline

  • member icon


Reputation: 4278
  • View blog
  • Posts: 13,437
  • Joined: 25-December 09

Re: (Inheritance) No Runtime Error, but Incorrect Output

Posted 25 January 2013 - 03:16 PM

You also have a couple of other problems:

Quote

In constructor ‘Account::Account()’:|
warning: ‘Account::balance’ should be initialized in the member initialization list [-Weffc++]|
warning: base class ‘class Account’ has a non-virtual destructor [-Weffc++]|
warning: base class ‘class Account’ has a non-virtual destructor [-Weffc++]|
In constructor ‘Account::Account(double)’:|
warning: ‘Account::balance’ should be initialized in the member initialization list [-Weffc++]|
In constructor ‘CheckingAccount::CheckingAccount(double, double)’:|
warning: declaration of ‘transactionFee’ shadows a member of 'this' [-Wshadow]|
warning: ‘CheckingAccount::transactionFee’ should be initialized in the member initialization list [-Weffc++]|
warning: unused parameter ‘initialBalance’ [-Wunused-parameter]|
In constructor ‘SavingsAccount::SavingsAccount(double, double)’:|
warning: declaration of ‘interestRate’ shadows a member of 'this' [-Wshadow]|
warning: ‘SavingsAccount::interestRate’ should be initialized in the member initialization list [-Weffc++]|
warning: unused parameter ‘initialBalance’ [-Wunused-parameter]|
In member function ‘double SavingsAccount::calculateInterest(double, double)’:|
warning: declaration of ‘interestRate’ shadows a member of 'this' [-Wshadow]|
warning: declaration of ‘balance’ shadows a member of 'this' [-Wshadow]|
||=== Build finished: 0 errors, 12 warnings ===|

You seem to be using the same name for parameters as your class member variables. I also suggest you start using initialization lists to initialize all of your class member variables.

Jim

This post has been edited by jimblumberg: 25 January 2013 - 03:19 PM

Was This Post Helpful? 2
  • +
  • -

#4 AnalyticLunatic  Icon User is offline

  • D.I.C Lover

Reputation: 223
  • View blog
  • Posts: 1,035
  • Joined: 25-June 12

Re: (Inheritance) No Runtime Error, but Incorrect Output

Posted 28 January 2013 - 02:01 PM

Thanks to you both. I ended up changing the Constructor declarations to pass the balance instead of the interest rate and transaction fee (doh!) and then had a few more issues with the intRate and transFee that were fixed through the use of a few get/set statements. It may not be the prettiest, but it does work correctly now.

Again,

Posted Image
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1