Virtual Function help

Hi ppl, i am having difficulty in declaring virtual functions for abstract classes. I have this assignment due next week. I am trying to implement types of account of a bank account class. The virtual functions are deposit and withdraw, each behave differently depending on the account type selected by user.

Account.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 #ifndef ACCOUNT_H
#define ACCOUNT_H

class Account
{
	char FName[32];
	char LName[32];
	char SIN[12];
	char AccType[10];

protected:
	double balance;
	unsigned int nCount;
	

public:
	Account () {}
	Account (char *szFName, char *szLName, char *szSIN, double dBalance, char *szAccType);
	virtual int Deposit (double &dBalance, unsigned int &nCount) = 0;
	virtual int Withdraw (double &dBalance, unsigned int &nCount) = 0;
	char *getFName (void);
	char *getLName (void);
	char *getAccType (void);
	char *getSIN (void);
	double getBalance (void);
	unsigned int getTotalTransactions (void);

	
};


#endif 


Account.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "Account.h"
#include <string.h>

Account::Account(char * szFName, char * szLName, char * szSIN, double dBalance, char * szAccType)
{
	strcpy(FName, szFName);
	strcpy(LName, szLName);
	strcpy(SIN, szSIN);
	strcpy(AccType, szAccType);
	balance = dBalance;
	

}

char *Account::getFName(void)
{
	return FName;
}

char *Account::getLName(void)
{
	return LName;
}

char *Account::getSIN(void)
{
	return SIN;
}

char *Account::getAccType(void)
{	
	
	return AccType;
}

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

unsigned int Account::getTotalTransactions(void)
{
	return nCount;

}


CheckingAcc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef CHECKINGACC_H
#define CHECKINGACC_H
#include <iostream>
#include <string.h>
#include "Account.h"

using namespace std;

class CheckingAcc : public Account
{
public:
	CheckingAcc(char *szFName, char *szLName, char *szSIN, double dBalance) :
		getAccType("Checking")
		{
		
		}

	virtual int Deposit(double &dBalance, unsigned int &nCount)
	{

		{
			if (balance < 0)
				cout << "Cannot deposit an amount less than $0.00" << endl;
			else
				dBalance = dBalance;
		}

		
		return 0;
	}

	virtual int Withdraw(double &dBalance, unsigned int &nCount)
	{
		{
			if (balance < 0)
				cout << "Cannot withdraw an amount less than $0.00" << endl;
			else if (dBalance > balance)
				cout << "Cannot withdraw an amount greater than the current balance" << endl;
			else
				balance = dBalance - balance;
		}

					
		if (balance < 4000)
		{
			balance = balance - 5.0;
		}

		return 0;
	}
		
};

#endif 


SavingAcc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#ifndef SAVINGACC_H
#define SAVINGACC_H
#include <iostream>
#include <string.h>
#include "Account.h"

using namespace std;

class SavingAcc : public Account
{
	
public:
	SavingAcc (char *szFName, char *szLName, char *szSIN, double dBalance) :
	 getAccType("Saving"){}
	
	virtual int withdraw(double &dBalance, unsigned int &nCount)
	{
		{
			if (balance < 0)
				cout << "Cannot withdraw an amount less than $0.00" << endl;
			else if (dBalance > balance)
				cout << "Cannot withdraw an amount greater than the current balance" << endl;
			else
				balance = dBalance - balance;
		}

		
		return 0;			

	}

	virtual int deposit(double &dBalance, unsigned int &nCount)
	{
		
		{
			if (dBalance < 0)
				cout << "Cannot deposit an amount less than $0.00" << endl;
			else
				balance = balance + dBalance;
		}

		return 0;
	}

};

#endif


VIPAcc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#ifndef VIPACC_H
#define VIPACC_H
#include <iostream>
#include <string.h>
#include "Account.h"

using namespace std;

class VIPAcc : public Account
{
public:
	VIPAcc(char *szFName, char *szLName, char *szSIN, double dBalance) : Account("VIP") {}

	virtual int deposit(double &dBalance, unsigned int &nCount)
	{
		{
			if (balance < 0)
				cout << "Cannot deposit an amount less than $0.00" << endl;
			else
				balance += dBalance;
		}

		if (dBalance > 10000)
		{
			balance = balance + dBalance + 6.0;
		}

		return 0;
	}

	virtual int withdraw(double &dBalance, unsigned int &nCount)
	{

		{
			if (dBalance < 0)
				cout << "Cannot withdraw an amount less than $0.00" << endl;
			else if (dBalance > balance)
				cout << "Cannot withdraw an amount greater than the current balance" << endl;
			else
				balance -= dBalance;
		}

		return 0;

	}
	
	
};

#endif 



Main code is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>
#include <string>

#include "SavingAcc.h"
#include "CheckingAcc.h"
#include "VIPAcc.h"

using namespace std;

void AccStatement(Account *acc);
void Transaction(Account *acc);

#define MAX_ACCOUNTS 3
#define MAX_TRANSACTIONS 5

int main()
{
	char szFName[32];
	char szLName[32];
	char szSIN[12];
	char szAccType[10];
	double dBalance;
	int op;
	Account *acc[MAX_ACCOUNTS];
	int count = 0;
	while (count<MAX_ACCOUNTS)
	{
		cout << "Customer's First Name : " << flush;
		cin >> szFName;
		cout << "Customer's Last Name : " << flush;
		cin >> szLName;
		cout << "Customer's SIN : " << flush;
		cin >> szSIN;
		cout << "Account Type : " << flush;				
		cin >> szAccType;
		cout << "Opening Balance : " << flush;
		cin >> dBalance;

		if (!strcmp(szAccType, "Checking"))
			acc[count] = new CheckingAcc(szFName, szLName, szSIN, dBalance);
		else if (!strcmp(szAccType, "VIP"))
			acc[count] = new VIPAcc(szFName, szLName, szSIN, dBalance);
		else if (!strcmp(szAccType, "Saving"))
			acc[count] = new SavingAcc(szFName, szLName, szSIN, dBalance);
		else
		{
			cout << "Incorect account type." << endl;
			continue;
		}
		count++;
	}

	for (count = 0; count<MAX_ACCOUNTS; count++)
	{
		cout << acc[count]->getAccType() << " account. Owner: "
			 << acc[count]->getFName() << " "
			 << acc[count]->getLName() << endl;
		for (op = 0; op<MAX_TRANSACTIONS; op++)
		{
			Transaction(acc[count]);
		}
	}

	// Display the balance
	for (count = 0; count<MAX_ACCOUNTS; count++)
		AccStatement(acc[count]);

	for (count = 0; count<MAX_ACCOUNTS; count++)
		delete acc[count];
	return (0);
}


void Transaction(Account *acc)
{
	char chTran;
	double dBalance;
	unsigned int nCount;

	cout << "Enter amount : " << flush;
	cin >> dBalance;
	cout << "Deposit (d), Withdraw (w):" << flush;
	cin >> chTran;
	if (chTran == 'd' || chTran == 'D')
	{
		acc->Deposit(dBalance, nCount);
	}
	else if (chTran == 'w' || chTran == 'W')
	{
		acc->Withdraw(dBalance, nCount);
	}
	cout << "Balance = " << dBalance
		<< "  Total Transactions = " << nCount << endl;
}


void AccStatement(Account *acc)
{
	cout << "Customer: " << acc->getFName() << " " << acc->getLName() << endl;
	cout << "Accunt type: " << acc->getAccType() << endl;
	cout << "Present Balance: " << acc->getBalance() << endl;
	cout << "Total Transactions: " << acc->getTotalTransactions() << endl;
	cout << endl;
}


I am getting this error.

"getAccType" is not a nonstatic data member or base class of class "CheckingAcc"
It's not really an issue with virtual functions. I didn't test it, but at the first glance, you seem to have implemented the virtual functions correctly. The problem is that you are not initializing the base class correctly when you instantiate derived classes.

Your base class, Account, is default constructible. And that is fine because you need to be able to create an array of Account type. Your base class can also be constructed with some parameters. When you instantiate derived classes, CheckingAcc, SavingAcc, and VIPAcc, you want to invoke the second constructor(That is the constructor that accept parameters) of the base class.

1
2
3
CheckingAcc(char *szFName, char *szLName, char *szSIN, double dBalance)
: Account{szFName, szLName, szSIN, dBalance, "Checking" }
{}


1
2
3
SavingAcc (char *szFName, char *szLName, char *szSIN, double dBalance)
: Account{szFName, szLName, szSIN, dBalance, "Saving"}
{}


1
2
3
VIPAcc(char *szFName, char *szLName, char *szSIN, double dBalance)
: Account{ szFName, szLName, szSIN, dBalance, "VIP" }
{}


Also, note that the functions Withdraw() and Deposit() in Account have the first character capitalized. In VIPAcc and SavingAcc, you have 'w'ithdraw() and 'd'eposit() instead of 'W'ithdraw() and 'D'eposit(). You end up creating new virtual functions instead of providing implementation for existing virtual functions. You will want to fix that.
Last edited on
Thanks for pointing that out, I have fixed the capitalizing in pure virtual function declaration.
i have fixed both the issues. Can you tell me why you choose {} for invoking second constructor?

i used this syntax
1
2
3
SavingAcc (char *szFName, char *szLName, char *szSIN, double dBalance)
: Account(szFName, szLName, szSIN, dBalance, "Saving")
{}
Last edited on
> Can you tell me why you choose {} for invoking second constructor?

You can use () to invoke the constructor and I believe most people do it that way and are taught to do it that way.

I personally like to use {} for any initialization and constructors and try to use () strictly for function calls.
Thanks for clearing that out. My program is compiling fine now.
Now i cannot figure out how to implement virtual functions for different account types.
My assignment tells me an example:
1) For Saving accounts:
a) For every third deposit there is a $1 fee deducted from the account
b) For every third withdraw there is a $2 fee deducted from the account

Does that mean i have to make two new protected variables in Account class (noWithdraws, noDeposits) and set them equal to nCount when function is called and then increment?


> Account, is default constructible. And that is fine because you need to be
> able to create an array of Account type.
`Account' is an abstract class, you can't create objects of type `Account', much less an array. There is no need for it to be default constructible.

In OP's code there is an array of pointers.


> Now i cannot figure out how to implement virtual functions for different
> account types.
virtual int Deposit(double &dBalance, unsigned int &nCount) ¿do you deposit a balance? ¿who should be responsible to track the number of operations?
stop coding, go (back) to the paper.

Also, dBalance = dBalance; //A=A


> For every third deposit there is a $1 fee deducted from the account
¿so the bank is charging me for giving them money? ¡what a great system!


> Does that mean i have to make two new protected variables in Account
> class (noWithdraws, noDeposits) and set them equal to nCount when
> function is called and then increment?
¿what kind of question is that? Go ahead, try it, and when you fail come here to ask.


By the way, if you need to post several files, instead upload to github or similar.
Last edited on
> Account, is default constructible. And that is fine because you need to be
> able to create an array of Account type.
`Account' is an abstract class, you can't create objects of type `Account', much less an array. There is no need for it to be default constructible.

In OP's code there is an array of pointers.


You're right. My apologies.
Another edit of post::::
Need help with implementation of checkingAcc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
virtual void Withdraw(double &dBalance, unsigned int &nCount)
	{
		nCount = withdraws;

		if (dBalance < 0)
		     cout << "Cannot withdraw an amount less than $0.00" << endl;
	        else if (balance < dBalance)
			cout << "Cannot withdraw an amount greater than the current balance" << endl; 
		else
			balance -= dBalance;
		withdraws++;
		
			
		if (balance < 4000)
			balance =balance - 5.0;		
		
	
	}

How do i implement this code so fee is deducted only after all the transactions are performed. My code is deducting -5 after each transaction is performed.

Edited: Each time user loses $5. Stupid bank..... :@
Last edited on
Thanks for the help ppl. hopefully m gona 100% on this assignment.
BTW while working on it I found this is a really flawed model of a banking system which made it even more confusing for me.
Topic archived. No new replies allowed.