Piggybank Homework help

Pages: 12
I'm getting a few errors, also I'm struggling with how to approach coding the addCoins function in order to keep the weight under the declared constant THREE_LBS in the PiggyBank.cpp file. Any help would be immensely appreciated.

The errors I'm getting are:
1
2
3
4
error LNK2019: unresolved external symbol "public: __thiscall Dimes::Dimes(int)" (??0Dimes@@QAE@H@Z) referenced in function _main
1>Lab6B.obj : error LNK2019: unresolved external symbol "public: __thiscall Nickels::Nickels(int)" (??0Nickels@@QAE@H@Z) referenced in function _main
1>Lab6B.obj : error LNK2019: unresolved external symbol "public: __thiscall Pennies::Pennies(int)" (??0Pennies@@QAE@H@Z) referenced in function _main
1>Lab6B.obj : error LNK2019: unresolved external symbol "public: __thiscall Quarters::Quarters(int)" (??0Quarters@@QAE@H@Z) referenced in function _main


Coins.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
ifndef COINS_H
#define COINS_H

const int PENNY      = 1;
const int NICKEL     = 5;
const int DIME       = 10;
const int QUARTER    = 25; 
const int HALFDOLLAR = 50; 

class Coins
{
    private:
        int    number;
        int    type;
        double value;
        double weight;
    public:
		Coins();
        Coins (int, int); 
        int    getNumber();
        int    getType();
        double getValue();
        double getWeight();
        void   print();
}; 

class Pennies : public Coins
{   
    public:
        Pennies (int number = 0);

        static const double VALUE;  //= 0.01;
        static const double WEIGHT; //= 2.500;     // grams
};

class Nickels : public Coins
{
    public:
        Nickels (int number = 0);

        static const double VALUE;  //= 0.05;
        static const double WEIGHT; //= 5.000;     // grams
};

class Dimes : public Coins
{
    public:
        Dimes (int number = 0); 

        static const double VALUE;  //= 0.10;
        static const double WEIGHT; //= 2.268;     // grams
};

class Quarters : public Coins
{
    public:
        Quarters (int number = 0); 
        
        static const double VALUE;  //= 0.25; 
        static const double WEIGHT; //= 5.670;     // grams
};

class HalfDollars : public Coins
{
    public:
        HalfDollars (int number = 0); 
        
        static const double VALUE;  //= 0.50; 
        static const double WEIGHT; //= 11.340;    // grams
};

#endif 


Coins.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
#include <iostream>
#include <cstdlib>
#include "Coins.h"
using namespace std;

const double Pennies::VALUE     = 0.01;
const double Nickels::VALUE     = 0.05;
const double Dimes::VALUE       = 0.10;
const double Quarters::VALUE    = 0.25;

const double Pennies::WEIGHT     = 2.500;
const double Nickels::WEIGHT     = 5.000;
const double Dimes::WEIGHT       = 2.268;
const double Quarters::WEIGHT    = 5.670;

Coins::Coins()
{
	number = 0;
	type = 0;
}

int Coins::getNumber()
{
	return number;
}
int Coins::getType()
{
	return type;
}
double Coins::getValue()
{
	return value;
}
double Coins::getWeight()
{
	return weight;
}
void Coins::print()
{
	cout << number << " " << type << " (" << value << ") " << "(" << weight << ")" << endl;
}


PiggyBank.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 PIGGYBANK_H
#define PIGGYBANK_H
#include "Coins.h"

using namespace std;

const double THREE_LBS = 1360.783;  // grams

class PiggyBank
{
    public:
        PiggyBank();
      
        void addCoins (Coins& c); 

        void removeCoins (int amount); 
        
        double getValue();
        
        double getWeight();
		
		void print();
  
    private:
        int     numPennies;
        int     numNickels;
        int     numDimes;
        int     numQuarters;
        double  value;
        double  weight;
};
#endif 


PiggyBank.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
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
#include <iostream>
#include <cstdlib>
#include "PiggyBank.h"
#include "Coins.h"
using namespace std;

PiggyBank::PiggyBank()
{
	numPennies = 0;
    numNickels = 0;
    numDimes = 0;
    numQuarters = 0;
    value = 0.0;
    weight = 0.0;
}

void PiggyBank::addCoins (Coins& c) 
{

	if(weight < THREE_LBS)
	{
	}
	else
	{
		cout << "Piggy bank weight exceeded! No coins added." << endl;
	}
}

void PiggyBank::removeCoins (int amount) 
{
	if(amount < value)
	{
		if (amount > QUARTER)
		{
			numQuarters = 0;
			weight = weight - Quarters::WEIGHT;
			value = value - Quarters::VALUE;
		
			if(amount > DIME)
			{
				numDimes = 0;
				weight = weight - Dimes::WEIGHT;
				value = value - Dimes::VALUE;

				if(amount > NICKEL)
				{
						numNickels = 0;
						weight = weight - Nickels::WEIGHT;
						value = value - Nickels::VALUE;
						
							if(amount > PENNY)
							{
								numPennies = 0;
								weight = weight - Pennies::WEIGHT;
								value = value -	Pennies::VALUE;
							}
							else
							{	
								numPennies = numPennies -	amount;
							}
					}
					else
					{
						numNickels = numNickels -	amount;
					}
			}
			else
			{
				numDimes = numDimes -	amount;
			}
		}	

		else
		{
			numQuarters = numQuarters -	amount;
		}
	}
	else
	{
		cout << "Piggy bank has insufficient funds to honor this request." << endl;
	}
}
double PiggyBank::getValue()
{
	return value;
}
double PiggyBank::getWeight()
{
	return weight;
}
void PiggyBank::print()
{
	cout << "Piggy bank now has:" << endl;
	cout << numPennies << " pennies, " << numNickels << " nickels, " 
		 << numDimes << " dimes, and " << numQuarters << " quarters." << endl;
	cout << "The total worth is $" << value << endl;
	cout << "with the coins weighing " << weight << endl;
}


Main
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
#include <iostream>
#include <cstdlib>
#include "PiggyBank.h"
#include "Coins.h"

using namespace std;

int main() 
{
    // Create an empty PiggyBank

    PiggyBank bank;  
    
    // Adding only quarters to test the removeCoins function

    Quarters q0(4);
    cout << "Adding: ";		
    q0.print();
    bank.addCoins (q0);	
    bank.print();
    
    double amt = .36;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
    
    bank.print();
    
    // Testing the Insufficient funds message
    
    amt = 1.63;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
    
    bank.print();
       
    // Creating Coins to fill the bank

    Pennies  p1(38);
    Nickels  n1(86);
    Dimes    d1(48);
    Quarters q1(38);
    Pennies  p2(26);
    Nickels  n2(55);
    Dimes    d2(74);
    Quarters q2(23);
    
    // Filling the bank

    cout << "Adding: ";		
    p1.print();
    bank.addCoins (p1);	
    
    cout << "Adding: ";
	n1.print();
    bank.addCoins (n1);

    cout << "Adding: ";
	d1.print();
	bank.addCoins (d1);	
	
    cout << "Adding: ";
	q1.print();
	bank.addCoins (q1);	

    cout << "Adding: ";		
    p2.print();
    bank.addCoins (p2);	
    
    cout << "Adding: ";
	n2.print();
    bank.addCoins (n2);

    // Testing the too heavy message

    cout << "Adding: ";
	d2.print();
	bank.addCoins (d2);	
	
    cout << "Adding: ";
	q2.print();
	bank.addCoins (q2);	
	
	bank.print();

    // Testing the remove function thoroughly

    amt = 27.53;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
	
    bank.print();

  system("pause");
  return 0;
}

Last edited on
Your problem is that your subclasses all have their constructors declared, but the constructor body is never implemented. And I don't see a reason why would you need a constructor that takes parameter number. Where would you use it if these classes have no properties that can be modified? Just remove constructors from subclasses declarations (fast way) or implement it.
Last edited on
Ahhhh ok, I see I think code is starting to blur together I missed that completely...

does anyone have any insight on how to start the addCoins function?? Is the if statement the right start or would I do better doing something else?
Last edited on
The switch statement would be a good choice here:

1
2
3
4
5
6
7
8
9
10
11
12
switch(c.type) 
{
    case(PENNY):
        numPennies++;
        break;
    //other cases follow
}

// For this to work your subclasses need their constructors
// to set their value and weight:
value += c.value;
weight += c.weight;
Mkay I think I got it so this is what I have so far for the addCoins and removeCoins functions, I'm getting errors however saying that variable type is inaccessible?

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
void PiggyBank::addCoins (Coins& c) 
{
	while (weight < THREE_LBS)
	{
		switch(c.type) 
		{
			case(PENNY):
					numPennies++;
					value += Pennies::VALUE;
					weight += Pennies::WEIGHT;
					break;
			case(NICKEL):
					numNickels++;
					value += Nickels::VALUE;
					weight += Nickels::WEIGHT;
					break;
			case(DIME):
					numDimes++;
					value += Dimes::VALUE;
					weight += Dimes::WEIGHT;
					break;
			case(QUARTER):
					numQuarters++;
					value += Quarters::VALUE;
					weight += Quarters::WEIGHT;
					break;
			default:
					break;
		}
	}
		cout << "Piggy bank weight exceeded! No coins added." << endl;
}

void PiggyBank::removeCoins (int amount) 
{
	if(amount < value)
	{
		if (amount > QUARTER)
		{
			numQuarters = 0;
			weight = weight - Quarters::WEIGHT;
			value = value - Quarters::VALUE;
		
			if(amount > DIME)
			{
				numDimes = 0;
				weight = weight - Dimes::WEIGHT;
				value = value - Dimes::VALUE;

				if(amount > NICKEL)
				{
						numNickels = 0;
						weight = weight - Nickels::WEIGHT;
						value = value - Nickels::VALUE;
						
							if(amount > PENNY)
							{
								numPennies = 0;
								weight = weight - Pennies::WEIGHT;
								value = value -	Pennies::VALUE;
							}
							else
							{	
								numPennies = numPennies -	amount;
							}
					}
					else
					{
						numNickels = numNickels -	amount;
					}
			}
			else
			{
				numDimes = numDimes -	amount;
			}
		}	

		else
		{
			numQuarters = numQuarters -	amount;
		}
	}
	else
	{
		cout << "Piggy bank has insufficient funds to honor this request." << endl;
	}
}
Last edited on
1. Rewrite remove to also use switch - it will look better.

2. Right, the inaccesible stuff happens because value and weight are private and piggybank class is stranger to coin class. You have 3 options:
A. Make value and weight public
B. Create public accessor function (eg. getValue) that returns value but does not allow to change it
C. Make piggybank class a friend class of coin

3. You dont need to repeat
1
2
value += c.value;
weight += c.weight;

Just write them once below the switch - they are common for all coin types.

Also, you should make coin private members protected, or subclasses will get the same inaccessible error when they get their own functions.
Last edited on
How do you makes coin members protected? It compiles now but I just get garbage code back...also will the while loops I'm implementing give me an infinite loop, or have I implemented them correctly?

Updated PiggyBank.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
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
#include <iostream>
#include <cstdlib>
#include "PiggyBank.h"
#include "Coins.h"
using namespace std;

PiggyBank::PiggyBank()
{
	numPennies = 0;
    numNickels = 0;
    numDimes = 0;
    numQuarters = 0;
    value = 0.0;
    weight = 0.0;
}

void PiggyBank::addCoins (Coins& c) 
{
	while (weight < THREE_LBS)
	{
		switch(c.type) 
		{
			case(PENNY):
					numPennies++;
					break;
			case(NICKEL):
					numNickels++;
					break;
			case(DIME):
					numDimes++;
					break;
			case(QUARTER):
					numQuarters++;
					break;
			default:
					break;
		}
			value += c.value;
			weight += c.weight;
	}
		cout << "Piggy bank weight exceeded! No coins added." << endl;
}

void PiggyBank::removeCoins (int amount) 
{
	while (amount < value)
	{
		switch(amount) 
		{
			case(PENNY):
					numPennies--;
					value -= Pennies::VALUE;
					weight -= Pennies::WEIGHT;
					break;
			case(NICKEL):
					numNickels--;
					value -= Nickels::VALUE;
					weight -= Nickels::WEIGHT;
					break;
			case(DIME):
					numDimes--;
					value -= Dimes::VALUE;
					weight -= Dimes::WEIGHT;
					break;
			case(QUARTER):
					numQuarters--;
					value -= Quarters::VALUE;
					weight -= Quarters::WEIGHT;
					break;
			default:
					break;
		}
	}
		cout << "Piggy bank has insufficient funds to honor this request." << endl;
}
double PiggyBank::getValue()
{
	return value;
}
double PiggyBank::getWeight()
{
	return weight;
}
void PiggyBank::print()
{
	cout << "Piggy bank now has:" << endl;
	cout << numPennies << " pennies, " << numNickels << " nickels, " 
		 << numDimes << " dimes, and " << numQuarters << " quarters." << endl;
	cout << "The total worth is $" << value << endl;
	cout << "with the coins weighing " << weight << endl;
}


Updated Coins.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
#include <iostream>
#include <cstdlib>
#include "Coins.h"
using namespace std;

const double Pennies::VALUE     = 0.01;
const double Nickels::VALUE     = 0.05;
const double Dimes::VALUE       = 0.10;
const double Quarters::VALUE    = 0.25;

const double Pennies::WEIGHT     = 2.500;
const double Nickels::WEIGHT     = 5.000;
const double Dimes::WEIGHT       = 2.268;
const double Quarters::WEIGHT    = 5.670;

Coins::Coins()
{
	number = 0;
	type = 0;
}

int Coins::getNumber()
{
	return number;
}
int Coins::getType()
{
	return type;
}
double Coins::getValue()
{
	return value;
}
double Coins::getWeight()
{
	return weight;
}
void Coins::print()
{
	cout << number << " " << type << " (" << value << ") " << "(" << weight << ")" << endl;
}


Updated PiggyBank.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
#ifndef PIGGYBANK_H
#define PIGGYBANK_H
#include "Coins.h"

using namespace std;

const double THREE_LBS = 1360.783;  // grams

class PiggyBank
{
    public:
        PiggyBank();
      
        void addCoins (Coins& c); 

        void removeCoins (int amount); 
        
        double getValue();
        
        double getWeight();
		
		void print();
  
		friend class Coins;

    private:
        int     numPennies;
        int     numNickels;
        int     numDimes;
        int     numQuarters;
        double  value;
        double  weight;
};
#endif 


Updated Coins.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
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
#ifndef COINS_H
#define COINS_H

const int PENNY      = 1;
const int NICKEL     = 5;
const int DIME       = 10;
const int QUARTER    = 25; 
const int HALFDOLLAR = 50; 

class Coins
{
    private:
        int    number;
        int    type;
        double value;
        double weight;
    public:
		Coins(); 
        int    getNumber();
        int    getType();
        double getValue();
        double getWeight();
        void   print();
		friend class PiggyBank;
}; 

class Pennies : public Coins
{   
    public:
        Pennies (int number = 0)
		{
		}

        static const double VALUE;  //= 0.01;
        static const double WEIGHT; //= 2.500;     // grams
};

class Nickels : public Coins
{
    public:
        Nickels(int number = 0)
		{
		}

        static const double VALUE;  //= 0.05;
        static const double WEIGHT; //= 5.000;     // grams
};

class Dimes : public Coins
{
    public:
        Dimes(int number = 0)
		{
		}

        static const double VALUE;  //= 0.10;
        static const double WEIGHT; //= 2.268;     // grams
};

class Quarters : public Coins
{
    public:
        Quarters(int number = 0)
		{

		}
        
        static const double VALUE;  //= 0.25; 
        static const double WEIGHT; //= 5.670;     // grams
};

class HalfDollars : public Coins
{
    public:
        HalfDollars (int number = 0); 
        
        static const double VALUE;  //= 0.50; 
        static const double WEIGHT; //= 11.340;    // grams
};

#endif 


Main
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
#include <iostream>
#include <cstdlib>
#include "PiggyBank.h"
#include "Coins.h"

using namespace std;

int main() 
{
    // Create an empty PiggyBank

    PiggyBank bank;  
    
    // Adding only quarters to test the removeCoins function

    Quarters q0(4);
    cout << "Adding: ";		
    q0.print();
    bank.addCoins (q0);	
    bank.print();
    
    double amt = .36;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
    
    bank.print();
    
    // Testing the Insufficient funds message
    
    amt = 1.63;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
    
    bank.print();
       
    // Creating Coins to fill the bank

    Pennies  p1(38);
    Nickels  n1(86);
    Dimes    d1(48);
    Quarters q1(38);
    Pennies  p2(26);
    Nickels  n2(55);
    Dimes    d2(74);
    Quarters q2(23);
    
    // Filling the bank

    cout << "Adding: ";		
    p1.print();
    bank.addCoins (p1);	
    
    cout << "Adding: ";
	n1.print();
    bank.addCoins (n1);

    cout << "Adding: ";
	d1.print();
	bank.addCoins (d1);	
	
    cout << "Adding: ";
	q1.print();
	bank.addCoins (q1);	

    cout << "Adding: ";		
    p2.print();
    bank.addCoins (p2);	
    
    cout << "Adding: ";
	n2.print();
    bank.addCoins (n2);

    // Testing the too heavy message

    cout << "Adding: ";
	d2.print();
	bank.addCoins (d2);	
	
    cout << "Adding: ";
	q2.print();
	bank.addCoins (q2);	
	
	bank.print();

    // Testing the remove function thoroughly

    amt = 27.53;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);
	
    bank.print();

  system("pause");
  return 0;
}
Oh, my bad, I assumed that remove function takes specific coin reference as argument and has slightly different purpose, sorry.

The cause of garbage data is that you ignored my comments in my code sample - initialize value and weight in subclasses' constructors with values specific to each type of coin.

As to protected keyword - as you can see, it is highlighted blue, because it is just another type of access. Replace private keyword with protected in your coin class and it will do.
Last edited on
Oh gosh wow I didn't even notice I did that ok, but in the instructors instructions it says:


These static variables are initialized at the top of the Coins.cpp file as:
const double Pennies::VALUE = 0.01;
const double Nickels::VALUE = 0.05;
const double Dimes::VALUE = 0.10;
const double Quarters::VALUE = 0.25;

const double Pennies::WEIGHT = 2.500;
const double Nickels::WEIGHT = 5.000;
const double Dimes::WEIGHT = 2.268;
const double Quarters::WEIGHT = 5.670;

The only member function that these derived classes have is a one-parameter constructor to set the number of coins in the particular object. This constructor passes the number and coin type to the Coins constructor to store in its data members.


How would I initialize value and weight as they're const values? I thought they had to be modifiable?
Well, that's confusing :) Untill now I assumed that one object of Coins class represents ONE coin . And it turns out that in fact that object represents one handfull of coins? Now I see why the number parameter was needed in the first place.
Ok, so to make as little changes as possible change the subclasses constructors to look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
Nickle::Nickle(int number)
{
    // each subclass has this line unique
    this.type = NICKLE; 

    this.number = number;
   
    //  This will set Coins::value to constat value of Nickles::VALUE:
    this.value = VALUE * number;   // value of this handfull of coins

    //  This will set Coins::weightto constat value of Nickles::WEIGHT:
    this.weight = WEIGHT * number;     
}

And for this to work, make coins private members protected:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Coins
{
    protected: // meaning subclasses can set and read these
        int    number;
        int    type;
        double value;
        double weight;
    public:
		Coins(); 
        int    getNumber();
        int    getType();
        double getValue();
        double getWeight();
        void   print();
		friend class PiggyBank;
}; 
Last edited on
I'm glad I'm not the only person who finds this confusing haha, thank you for your continued help, I'm just so frustrated with this class and my seemingly absentee professor, your help is making all the difference and I appreciate you immensely, I think some things are starting to click.

I'm getting an output that's not garbage code, yay! Making progress :) Output isn't quite there yet this is what I should be getting:


Adding: 4 quarters ($1.00) (22.68 grams)

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 4 quarters.
  The total worth is $1.00
  with the coins weighing 22.68 grams.

Requesting $0.36
Remove:
   0 pennies, 0 nickels, 0 dimes, and 2 quarters
   For a total of $0.50

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 2 quarters.
  The total worth is $0.50
  with the coins weighing 11.34 grams.

Requesting $1.63
Piggy bank has insufficient funds to honor this request

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 2 quarters.
  The total worth is $0.50
  with the coins weighing 11.34 grams.

Adding: 38 pennies ($0.38) (95.00 grams)
Adding: 86 nickels ($4.30) (430.00 grams)
Adding: 48 dimes ($4.80) (108.86 grams)
Adding: 38 quarters ($9.50) (215.46 grams)
Adding: 26 pennies ($0.26) (65.00 grams)
Adding: 55 nickels ($2.75) (275.00 grams)
Adding: 74 dimes ($7.40) (167.83 grams)
Piggy bank weight exceeded! No coins added.

Adding: 23 quarters ($5.75) (130.41 grams)

Piggy bank now has:
  64 pennies, 141 nickles, 48 dimes, and 63 quarters.
  The total worth is $28.24
  with the coins weighing 1331.07 grams.

Requesting $27.53
Remove:
   3 pennies, 139 nickels, 48 dimes, and 63 quarters
   For a total of $27.53

Piggy bank now has:
  61 pennies, 2 nickles, 0 dimes, and 0 quarters.
  The total worth is $0.71
  with the coins weighing 162.50 grams.


What I'm getting


Adding: 4 25 (1) (22.68)
Piggy bank weight exceeded! No coins added.
Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 60 quarters.
  The total worth is $60
  with the coins weighing 1360.8.
Requesting $0.36

Last edited on
The same mistake I made before is still :ffecting your add function
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
void PiggyBank::addCoins (Coins& c) 
{
	// old AND new coins must fit:
	if(weight  + c.weight < THREE_LBS) { 
		switch(c.type) 
		{
			case(PENNY):
					numPennies += c.number; // changed from ++
					break;
			case(NICKEL):
					numNickels+= c.number;
					break;
			case(DIME):
					numDimes+= c.number;
					break;
			case(QUARTER):
					numQuarters+= c.number;
					break;
			default:
					break;
		}
		value += c.value;
		weight += c.weight;
	}
	else { // this only happens if the above does not
		cout << "Piggy bank weight exceeded! No coins added." << endl;
	}
}
Last edited on
Ok I see, would I do the same for the remove coins function? I doesn't want to acknowledge that I'm removing coins, the parameter amount though I suppose indicates that I have to do something different than I did with addCoins, correct?
Yes, remove function obviously is not symetrical to add function. You should do it along these lines:
1. Create a local variable to hold total value of coins selected to be removed and set it to zero.

2. Create local variables to hold number of coins of each type and set it initially to zero.

3. For each coin type, starting from the ones with highest value, create a while loop. In each pass do 2 things: increment number of coins of given type by one (local variable from step 2) and add value of this coin to total (from step 1)

4. The loop should go while BOTH of these conditions are true:
==> A) You need more coins: (current total) + (one coin value) < amount (fuction argument)
==> B) You have more coins: (piggy.numQuarters) - (number of coins of this type) > 0 (numQuarters is just example, in each while loop you check for different coin types)

5. Repeat the loop for smaller coins, then again and again

6. At this step you should know how many of which coins is needed to be removed. So work on piggy bank and subtract total number of each coins from piggy.numQuarters, Dimes, etc, decrease weight by number of coins of each type * their weight, and the same with value.

7. Note one thing: this algorithm will result in one of two situations: you either have the exact coins needed to honor the request OR you may pick too little coins (if you only have one quarter in the bank, and need to pay out 10c you will pay nothing). To fix this you may do one last check at the end and in case your total is less than amount, and just add the one coin of the smallest type you have left. If it is impossible - you won't be able to honor the request at all.

I will leave the coding to you, but please share the results :)

Last edited on
Ok so something like this?

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
void PiggyBank::removeCoins (int amount) 
{
	double valueOfWithdrawal = 0;
	int pennies = 0;
	int nickels = 0;
	int dimes = 0;
	int quarters = 0;
	
	if (value*100 > amount)
	{
		while (value + QUARTER < amount && numQuarters - quarters > 0)
		{
			quarters++;
			valueOfWithdrawal = valueOfWithdrawal + Quarters::VALUE;
			numQuarters = numQuarters - quarters;
			weight = weight - quarters*(Quarters::WEIGHT);
			value =  value - quarters*(Quarters::VALUE);
		}
		while (value + DIME < amount && numDimes - dimes > 0)
		{
			dimes++;
			valueOfWithdrawal = valueOfWithdrawal + Dimes::VALUE;
			numDimes = numDimes - dimes;
			weight = weight - dimes*(Dimes::WEIGHT);
			value =  value - dimes*(Dimes::VALUE);
		}
		while (value + NICKEL < amount && numNickels - nickels > 0)
		{
			nickels++;
			valueOfWithdrawal = valueOfWithdrawal + Nickels::VALUE;
			numNickels = numNickels - nickels;
			weight = weight - nickels*(Nickels::WEIGHT);
			value =  value - nickels*(Nickels::VALUE);
		}
		while (value + PENNY < amount && numPennies - pennies > 0)
		{
			pennies++;
			valueOfWithdrawal = valueOfWithdrawal + Pennies::VALUE;
			numPennies = numPennies - pennies;
			weight = weight - pennies*(Pennies::WEIGHT);
			value =  value - pennies*(Pennies::VALUE);
		}

		cout << "Remove: " << endl;
		cout << pennies << " pennies, " << nickels << " nickels, " 
		<< dimes << " dimes, and " << quarters << " quarters." << endl; 
		cout << "For a total of $" << setprecision(2) << fixed << valueOfWithdrawal << endl << endl; 
	}
	else
	{
		cout << "Piggy bank has insufficient funds to honor this request." << endl << endl;
	}
}


It's close...I should be getting this output:


Adding: 4 quarters ($1.00) (22.68 grams)

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 4 quarters.
  The total worth is $1.00
  with the coins weighing 22.68 grams.

Requesting $0.36
Remove:
   0 pennies, 0 nickels, 0 dimes, and 2 quarters
   For a total of $0.50

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 2 quarters.
  The total worth is $0.50
  with the coins weighing 11.34 grams.

Requesting $1.63
Piggy bank has insufficient funds to honor this request

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 2 quarters.
  The total worth is $0.50
  with the coins weighing 11.34 grams.

Adding: 38 pennies ($0.38) (95.00 grams)
Adding: 86 nickels ($4.30) (430.00 grams)
Adding: 48 dimes ($4.80) (108.86 grams)
Adding: 38 quarters ($9.50) (215.46 grams)
Adding: 26 pennies ($0.26) (65.00 grams)
Adding: 55 nickels ($2.75) (275.00 grams)
Adding: 74 dimes ($7.40) (167.83 grams)
Piggy bank weight exceeded! No coins added.

Adding: 23 quarters ($5.75) (130.41 grams)

Piggy bank now has:
  64 pennies, 141 nickles, 48 dimes, and 63 quarters.
  The total worth is $28.24
  with the coins weighing 1331.07 grams.

Requesting $27.53
Remove:
   3 pennies, 139 nickels, 48 dimes, and 63 quarters
   For a total of $27.53

Piggy bank now has:
  61 pennies, 2 nickles, 0 dimes, and 0 quarters.
  The total worth is $0.71
  with the coins weighing 162.50 grams.


I'm getting


Adding: 4 quarters ($1.00) (22.68 grams)

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 4 quarters.
  The total worth is $1.00
  with the coins weighing 22.68 grams.

Requesting $0.36
Remove:
   0 pennies, 0 nickels, 0 dimes, and 2 quarters
   For a total of $0.50

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 1 quarters.
  The total worth is $0.25
  with the coins weighing 5.67 grams.

Requesting $1.63
Piggy bank has insufficient funds to honor this request

Piggy bank now has:
  0 pennies, 0 nickles, 0 dimes, and 1 quarters.
  The total worth is $0.25
  with the coins weighing 5.67 grams.

Adding: 38 pennies ($0.38) (95.00 grams)
Adding: 86 nickels ($4.30) (430.00 grams)
Adding: 48 dimes ($4.80) (108.86 grams)
Adding: 38 quarters ($9.50) (215.46 grams)
Adding: 26 pennies ($0.26) (65.00 grams)
Adding: 55 nickels ($2.75) (275.00 grams)
Adding: 74 dimes ($7.40) (167.83 grams)
Piggy bank weight exceeded! No coins added.

Adding: 23 quarters ($5.75) (130.41 grams)

Piggy bank now has:
  64 pennies, 141 nickles, 48 dimes, and 62 quarters.
  The total worth is $27.99
  with the coins weighing 1325.40 grams.

Requesting $27.53
Remove:
   10 pennies, 16 nickels, 9 dimes, and 10 quarters
   For a total of $4.30

Piggy bank now has:
  9 pennies, 5 nickles, 3 dimes, and 7 quarters.
  The total worth is $2.39
  with the coins weighing 93.99 grams.
Last edited on
I have a feeling I'm closer but the values are definitely off...
There are some errors, and the one first noticable is your amount argument type. If you expect your function to process values such as in your expected output: $27.53, the function is supposed to accept value in double type.
Then, there would not be a need for weird workarounds you tried to use in while conditions. What is this *100 supposed to mean anyway?
if (value*100 > amount)

This is another bug:
while (value + QUARTER < amount && numQuarters - quarters > 0)
In this line QUARTER has value of 25, but it represents a coin with value of $0.25. It is 100 times too much! You should rather use Quarter::VALUE instead, which has both type and value consistant with PiggyBank::value variable, so their sum makes sense in this statement. But...
This is not really what should be checked in this line, in my opinion, because I believe you should not change the PiggyBank::value until the end of the function, when you are able to verify you have enough coins of each type to make a successfull transaction. This is why you declared your temporary double valueOfWithdrawal = 0;.
As I see it, the function should look like this:
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
void PiggyBank::removeCoins (double amount) 
{
    // The real goal of this function is to verify if it is
    // possible to connect a number of coins in a way that
    // their total value is equal to the valueOfWithdrawal
    double valueOfWithdrawal = 0;
    int pennies = 0;
    int nickels = 0;
    int dimes = 0;
    int quarters = 0;
	
    if (amount <= value) // if enough money
    {
        while (valueOfWithdrawal + Quarter::VALUE < amount 
            && numQuarters - quarters > 0)
        {
            quarters++;
            valueOfWithdrawal = valueOfWithdrawal + Quarters::VALUE;
            // It is not yet time to change the real contents of piggy
            //numQuarters = numQuarters - quarters;
            //weight = weight - quarters*(Quarters::WEIGHT);
            //value =  value - quarters*(Quarters::VALUE);
        }
        while (valueOfWithdrawal + Dimes::VALUE < amount 
            && numDimes - dimes > 0)
        {
            dimes++;
            valueOfWithdrawal = valueOfWithdrawal + Dimes::VALUE;
        }
        while (valueOfWithdrawal + Nickels::VALUE < amount 
            && numNickels - nickels > 0)
        {
            nickels++;
            valueOfWithdrawal = valueOfWithdrawal + Nickels::VALUE;
        }
        while (valueOfWithdrawal + Pennies::VALUE < amount 
            && numPennies - pennies > 0)
        {
            pennies++;
            valueOfWithdrawal = valueOfWithdrawal + Pennies::VALUE;
        }
		
        // Assuming we have enough coins in each type in the bank, 
        // the valueOfWithdrawal is now equal requested amount, so
        // our function worked. There is a possibility, however, that
        // we do not have enough pennies (eg. we have two pennies, and need
        // to return $27.53 There is no way to proceed without at 
        // least 3 coins of penny size), even if we have $50 in quarters
        // alone. At this point you must decide: do you want your function
        // to:
        // 	A. Withdraw less than requested (eg. $27.52) - missing last penny
        //	B. Withdraw more than requested (eg. $27.60) - one extra dime 
        //	C. Inform the user that the request cannot be honoured.
        // The choice will afffect the rest of the program.
        //
        // ********* Case A: *******************
        if(valueOfWithdrawal != amount)
        {
            cout << "I do not have the change. Can I owe you $" 
            << amount - valueOfWithdrawal << "?";
        }
        // *************************************
        // ********* Case B: *******************
        if(valueOfWithdrawal != amount)
        {
            // This case is tricky, I partially explained it in my previous post
        }
        // *************************************
        // ********* Case C: *******************
        // Simply return, without any changes
        if(valueOfWithdrawal != amount)
        {
            cout << "Piggy bank lacks change to honor this request." 
                << endl << endl;
            return;
        }
        // *************************************
        
        // Now, that we know actual coin count, we can apply the change to the
        // piggy:
        double weightOfWithdrawal = pennies * Pennies::WEIGHT +
                                    nickels * Nickels::WEIGHT + 
                                    dimes * Dimes::WEIGHT + 
                                    quarters * Quarters::WEIGHT;
									
        value -= valueOfWithdrawal;
        weight -= weightOfWithdrawal;
                
        cout << "Remove: " << endl;
        cout << pennies  << " pennies, " 
            << nickels  << " nickels, " 
            << dimes 	 << " dimes, and " 
            << quarters << " quarters." << endl; 
        cout << "For a total of $" << setprecision(2) 
            << fixed << valueOfWithdrawal << endl << endl;
    }
    else
    {
        cout << "Piggy bank has insufficient funds to honor this request." 
            << endl << endl;
    }
}
Last edited on
The reason I put the *100 in is because in the instructor provided code for whatever reason he put

1
2
3
    amt = 27.53;	     
	cout << "Requesting $" << amt << endl;     
	bank.removeCoins(amt*100);


so the value entering the function is 100 times the amount, so I used the QUARTER values, and all... when I remove the numQuarters-= quarters; bit the code gives me entirely wrong values as it never registers I suppose, that I removed anything...then if I move it outside the if statement it just says:


Requesting $0.36
Remove:
   0 pennies, 0 nickels, 0 dimes, and 0 quarters
   For a total of $0.00
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double weightOfWithdrawal = pennies * Pennies::WEIGHT +
                            nickels * Nickels::WEIGHT + 
                            dimes * Dimes::WEIGHT + 
                            quarters * Quarters::WEIGHT;
									
value -= valueOfWithdrawal;
weight -= weightOfWithdrawal;
/* ******************************* */
// You are right - I forgot these, I intended to place them here
// after all the while loops are finished.
numQuarters -= quarters;
numDimes -= dimes;
numNickels -= nickels;
numPennies -= pennies;
// The reason I put them here, and not inside the whiles is because
// now, if anything goes wrong - like no small change - we can abort the 
// function without making any changes to the bank
/* ******************************* */
cout << "Remove: " << endl;
cout << pennies  << " pennies, " 
     << nickels  << " nickels, " 
     << dimes 	 << " dimes, and " 
     << quarters << " quarters." << endl; 


Can I see the exact assignment description? I sense there are quite a few bad design choices resulting from misunderstanding the requirements.
Last edited on
Sure its rather long but here:


Little Betsy is excited about the piggy bank she has received for Christmas.
Her parents have promised to give her their change every week for her to
add to the bank. The bank can safely hold only 3 pounds of coins. The coin
slot can only take pennies, nickels, dimes, and quarters. Betsy wants to keep
track of how much money she has in the bank at any given time. She also
wants to know which coins to remove when she needs to spend some money
from the bank.
Task:
Create a Piggy Bank program that has a base Coins class and five derived
classes called Pennies, Nickels, Dimes, and Quarters. The valid coins are
added to a PiggyBank class that keeps track of the number of each coin in
the bank, the total value of the coins in the bank and the total weight.
These derived classes are short and can be placed in the same file and the
base class. Thus, Coins.h will contain the class definitions for Coins,
Pennies, Nickels, Dimes, and Quarters. In addition, the Coins.cpp file will
contain the source code implementations of all the member functions in all
these same classes.

There are four global constants holding the integer value of each of the coin
types:
const int PENNY = 1;
const int NICKEL = 5;
const int DIME = 10;
const int QUARTER = 25;The Coins class has four data members:
int number
int type
double value
double weight
They hold the number of the particular coins being added to the bank, the
type of coin and the total value and weight the coins. These data members
each have a get function, but no set function:
int getNumber()
int getType()
double getValue()
double getWeight()
The Coins data members, number and type, are set through the
two-parameter constructor with default parameters. The constructor
calculates and stores the total value and weight: Coins (int = 0, int = 0).
In addition, the Coins class has a print function that displays the coin type,
number, total value and total weight:
void print()
The four classes derived from Coins have two static const data members.
They hold the individual coin value and weight (in grams) as doubles:
static const double VALUE
static const double WEIGHT
These static variables are initialized at the top of the Coins.cpp file as:
const double Pennies::VALUE = 0.01;
const double Nickels::VALUE = 0.05;
const double Dimes::VALUE = 0.10;
const double Quarters::VALUE = 0.25;
const double Pennies::WEIGHT = 2.500;
const double Nickels::WEIGHT = 5.000;
const double Dimes::WEIGHT = 2.268;
const double Quarters::WEIGHT = 5.670;
The only member function that these derived classes have is a
one-parameter constructor to set the number of coins in the particular
object. This constructor passes the number and coin type to the Coins
constructor to store in its data members.
The PiggyBank class has six data members:
int numPennies
int numNickelsint numDimes
int numQuarters
double value
double weight
These data members are set to zero in its only (default) constructor:
PiggyBank().
There are member functions to add coins and remove coins from the
PiggyBank. There are functions to return the PiggyBank value, weight and
the number of each type of coin. These functions are:
void addCoins (Coins&)
void removeCoins (int)
double getValue()
double getWeight()

The addCoins() member function should begin by checking the weight of the
coins it is trying to add. If adding the Coins object causes the total weight of
the PiggyBank to rise above three pounds, the addCoins() member function
should return an error message and not add the Coins.
The removeCoins() member function receives the amount to remove as a
number of cents. It should begin by comparing the value of the money it has
been requested to remove to the amount currently in the bank. If the bank
does not contain the requested amount, then the removeCoins() function
should return an error message and not remove the Coins.
Function Table for Piggy Bank Program:

return value function parameters Task:
none Coins int
number=0
int type=0
Two-parameter constructor with default values of zero. It sets
the number and type of coins. It calculates the value and the
weight
int getType none Returns the type of coin
int getNumber none Returns the number of coins
double getValue none Returns the total value of the coins
double getWeight none Returns the total weight of the coins
void print none Displays the coin type, number, total value and total weight. See
Sample Output.
none Pennies int number One-parameter constructor to set number of Pennies. It calls the
base Coins constructor setting this number and coin type of
PENNY.
none Nickels int number One- parameter constructor to set number of Nickels. It calls the
base Coins constructor setting this number and coin type of
NICKEL.
none Dimes int number One- parameter constructor to set number of Dimes. It calls the
base Coins constructor setting this number and coin type of
DIME.none Quarters int number One- parameter constructor to set number of Quarters. It calls
the base Coins constructor setting this number and coin type of
QUARTER.
none PiggyBank none Default constructor initializing all data members to 0 or 0.0.
double getValue none Returns the total value of the PiggyBank
double getWeight none Returns the total weight of the PiggyBank
void addCoins Coins& c Add coins to the PiggyBank, making sure that the total weight is
under 3 pounds. The number of coins of each particular type is
updated, as well as the total weight and value.void removeCoins int
amount
Remove coins from the PiggyBank getting the least number of
coins needed to fulfill the request. The coins are not removed
when the total value in the bank is less than the requested amount
which is given in cents. Note: you may have to remove more
money than the requested amount based on which coins are in
the bank.
More Instructions:
This programming exercise has five source code files:
1 Lab6B.cpp – This contains the main function (Driver Program) which is
used to test your class. It will be provided to you. DO NOT modify this
main function. Carefully, look at the calls to the PiggyBank class
member functions from this main function. You must code YOUR
PiggyBank class member functions such that this main function works
exactly as given. You WILL NOT be given any credit for your effort, if your
code does not work with this main function.
2 Coins.h – This contains the class definition for the Coins class and each of
the classes that are derived from Coins. This file will be provided for you.
3 Coins.cpp – This contains the source code implementations of the
member functions for Coins and the classes derived from Coins.
4 PiggyBank.h - This contains the class definition for the PiggyBank class.
This file will be provided for you.
5 PiggyBank.cpp - This contains the source code implementations of the
PiggyBank member function.
Pages: 12