stack overflow?

Getting warnings for my operator+=, -=, /=, *= ...what am I doing wrong??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DollarsCents& DollarsCents::operator+= (const DollarsCents& money)
{
	DollarsCents dc;
	dc += money;
	return *this;
}
DollarsCents& DollarsCents::operator-= (const DollarsCents& money)
{
	DollarsCents dc;
	dc -= money;
	return *this;
}
DollarsCents& DollarsCents::operator/=(const int num)
{
	DollarsCents dc;
	dc /= num;
	return *this;
}
DollarsCents& DollarsCents::operator*=(const int num)
{
	DollarsCents dc;
	dc *= num;
	return *this;
}



1
2
3
4
warning C4717: 'DollarsCents::operator+=' : recursive on all control paths, function will cause runtime stack overflow
warning C4717: 'DollarsCents::operator-=' : recursive on all control paths, function will cause runtime stack overflow
warning C4717: 'DollarsCents::operator/=' : recursive on all control paths, function will cause runtime stack overflow
warning C4717: 'DollarsCents::operator*=' : recursive on all control paths, function will cause runtime stack overflow
Last edited on
Here is my opinion on what is going on.

Warning C4717: Every path through a function contains a call to the function. Since there is no way to exit the function without first calling itself recursively, the function will never exit.

Line 3 You create a DollarCents object.

Line 4 You try to execute your operator overload on a DollarCents object.

So the compiler goes to its list of operators and says cool I have a method for dealing with DollarCents objects let me call it, cool I have a method for dealing with DollarCents objects let me call it, cool I have a method for dealing with DollarCents objects let me call it, and then we enter "Ground Hog Day."

So you just need to rethink your function logic.

Last edited on
mobotus is correct. Your operators are all calling themselves, so it's basically an infinite loop.


Also... your logic is incorrect anyway. The *=, +=, etc operators should be modifying this object... they should not be creating a new DollarsCents object.
Ok so I'm a bit confused then I think so would I do something like this?

1
2
3
4
5
DollarsCents& DollarsCents::operator+= (const DollarsCents& money)
{
	*this += money;
	return *this;
}


But now though its still recursive, I think I'm just missing something in terms of exiting it would I start a loop of some sort??
The problem is...

*this += money

Here... *this is a DollarsCents object. So what you're doing with this line of code is telling the computer to add two DollarsCents objects together.

The problem is... the computer doesn't know HOW to do that. The computer is going to look to your += operator to see how to add these two objects together.

So basically what's happening is this:

1) Computer needs to add two DollarsCents objects together.
2) It checks your += operator to see how to do that
3) Your += operator does it by adding two DollarsCents objects together
4) So in order to know how to add two DollarsCents objects, it needs to add two DollarsCents objects
5) So it checks your += operator to see how to do that
6) Your += operator does it by adding two DollarsCents objects together
7) etc
8) etc


Your += operator should be defining how to add the objects. So you probably need to access DollarsCents's members and add them rather than trying to add the object as a whole.
Last edited on
Ok, I think I understand so how would I do that? Would I do what I did for just my operator+ function?

1
2
3
4
5
	*this.dollars = dollars += money.dollars;
	*this.cents = cents += money.cents;

	*this.simplify();
	return *this;


however that tells me that the expression must have a class type...
Instead of
 
    *this.dollars = dollars += money.dollars;

simply
 
    dollars += money.dollars;
Oh lord I get it now, I think I've really been staring at this for too long, thank you all!! I'm getting some strange output though according to others in the class the sample output is completely wrong, so I'm not really sure where I stand in terms of this...if someone could check me that would be wonderful, I of course understand if you'd rather not...

my completed .cpp file
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
#include "DollarsCents.h"
using namespace std;

//friend functions
istream& operator>> (istream& in, DollarsCents& money)
{
	char dot;

    in >> money.dollars >> dot >> money.cents;

	cin >> dot;

    return in;

}
ostream& operator<< (ostream& out, const DollarsCents &money)
{
    out << "$" << money.dollars << "." << money.cents;
    return out;
}

//default constructor
DollarsCents::DollarsCents()
{
	dollars = 0;
	cents = 0;
}

//Two-parameter constructor
DollarsCents::DollarsCents (int dollars, int cents)
{
	if (cents < 0)
	{
		cents = 0;
	}
	simplify();
}

//Get Functions
int DollarsCents::getDollars() const
{
	return dollars;
}

int DollarsCents::getCents() const
{
	return cents;
}

//Calculation Functions
DollarsCents DollarsCents::operator+ (const DollarsCents& money)
{
	DollarsCents dc_add;

	dc_add.dollars = dollars + money.dollars;
	dc_add.cents = cents + money.cents;

	dc_add.simplify();

	return dc_add;
} 

DollarsCents DollarsCents::operator- (const DollarsCents& money)
{	
	DollarsCents dc_subtract;

	if(money.cents > cents) 
	{
	dc_subtract.dollars = (dollars - 1) - money.dollars;
	dc_subtract.cents = (cents + 100) - money.cents;
	}
	else
	{
	dc_subtract.dollars = dollars - money.dollars;
	dc_subtract.cents = cents - money.cents;
	}

	dc_subtract.simplify();

	return dc_subtract;
}

DollarsCents DollarsCents::operator/(const int num)
{
	int totalCents = (dollars*100) + cents;

	totalCents /= num;

	DollarsCents dc_divide(0, totalCents);

	dc_divide.simplify();
	
	return dc_divide;
}

DollarsCents DollarsCents::operator*(const int num)
{
	int totalCents = (dollars*100) + cents;

	totalCents *= num;
	
	DollarsCents dc_multiply(0, totalCents);
	
	dc_multiply.simplify();

	return dc_multiply;
}

DollarsCents& DollarsCents::operator+= (const DollarsCents& money)
{
	dollars += money.dollars;
	cents += money.cents;
	return *this;
}
DollarsCents& DollarsCents::operator-= (const DollarsCents& money)
{
	dollars -= money.dollars;
	cents -= money.cents;
	return *this;
}
DollarsCents& DollarsCents::operator/=(const int num)
{
	int totalCents = (dollars*100) + cents;

	totalCents /= num;

	return *this;
}
DollarsCents& DollarsCents::operator*=(const int num)
{
	int totalCents = (dollars*100) + cents;

	totalCents *= num;
	return *this;
}

//bool functions
bool DollarsCents::operator<(const DollarsCents& money) const
{
	DollarsCents dc;
	return (dollars < money.dollars && cents < dc.dollars && cents);
}
bool DollarsCents::operator<=(const DollarsCents& money) const
{
	DollarsCents dc;
	return (dollars <= money.dollars && cents <= dc.dollars && cents);
}
bool DollarsCents::operator>(const DollarsCents& money) const
{
	DollarsCents dc;
	return (dollars > money.dollars && cents > dc.dollars && cents);
}
bool DollarsCents::operator>=(const DollarsCents& money) const
{
	DollarsCents dc;
	return (dollars >= money.dollars && cents >= dc.dollars && cents);
}
bool DollarsCents::operator==(const DollarsCents& money) const
{
	DollarsCents dc;
    return (dollars == money.dollars && cents == dc.dollars && cents);
}
bool DollarsCents::operator!=(const DollarsCents& money) const
{
	DollarsCents dc;
	return (dollars != money.dollars && cents != dc.dollars && cents);
}


my completed .h file
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
#include <cstdlib>
#include <string>

using namespace std;

class DollarsCents
{

  public:
    // Constructors
    DollarsCents (int dollars, int cents);
	DollarsCents();

    // getters
    int getDollars() const;
    int getCents() const;
    
    //utility function that simplifies the data members dollars and cents so that 0 <= cents <100
	void DollarsCents::simplify()
	{		
		while (cents >= 100)
		{
			cents-=100;
			dollars++;
		}
	}
    
    // new object = this + money
    DollarsCents operator+ (const DollarsCents& money);     
    
    // new object = this - money
    DollarsCents operator- (const DollarsCents& money);     

    // new object = this * num
    DollarsCents operator* (const int num);     

    // new object = this / num
    DollarsCents operator/ (const int num);     

    // this = this + money
    DollarsCents& operator+= (const DollarsCents& money);     

    // this = this - money
    DollarsCents& operator-= (const DollarsCents& money);     

    // this *= num
	DollarsCents& operator*= (const int num);                    

    // this /= num
    DollarsCents& operator/= (const int num);                    
   
	// comparison operators
    bool operator== (const DollarsCents& money) const;               
    bool operator!= (const DollarsCents& money) const;              
    bool operator<  (const DollarsCents& money) const;               
    bool operator<= (const DollarsCents& money) const;               
    bool operator>  (const DollarsCents& money) const;               
    bool operator>= (const DollarsCents& money) const;               

    // Global friend functions supporting input/output.  
    // Use dollars, cents

    friend istream& operator>> (istream& in, DollarsCents& money); 
    friend ostream& operator<< (ostream& out, const DollarsCents &money);  

  private:
    int dollars;   // valid values: >0
    int cents;     // valid values: 0-99
};
#endif 


instructor provided code here...
http://codepad.org/4ofnMmST
*this.dollars

The . is happening before the *, so the complier thinks you are saying that this is a class ( not a pointer to the instance ).

You can do: (*this).dollars, but since this is such a common thing to want to do ( dereference a pointer and then use it ), we are given the -> operator:

this->dollars
Okk, I see I got it to compile but I'm getting some weirdness with my output..

What I should be getting:
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

Enter amount, dollars.cents : 22.2222
You entered $44.22
Enter amount, dollars.cents : 61.1111
You entered $72.11
Enter amount, dollars.cents : 10.3333
You entered $43.33

Testing: logical operators
$44.22 <  $44.22: false
$44.22 <= $44.22: true
$44.22 >  $44.22: false
$44.22 >= $44.22: true
$44.22 == $44.22: true
$44.22 != $44.22: false

$44.22 <  $72.11: true
$44.22 <= $72.11: true
$44.22 >  $72.11: false
$44.22 >= $72.11: false
$44.22 == $72.11: false
$44.22 != $72.11: true

$44.22 <  $43.33: false
$44.22 <= $43.33: false
$44.22 >  $43.33: true
$44.22 >= $43.33: true
$44.22 == $43.33: false
$44.22 != $43.33: true

Testing: DC1 + DC2 = DC3
$44.22 + $44.22 = $88.44
$44.22 + $72.11 = $116.33
$44.22 + $43.33 = $87.55

Testing: DC1 - DC2 = DC3
$72.11 - $44.22 = $27.89
$44.22 - $43.33 = $0.89

Testing: DC1 * int = DC2
$44.22 * 2 = $44.44
$72.11 * 2 = $72.22
$72.11 * 3 = $72.33
$43.33 * 3 = $43.99

Testing: DC1 / int = DC2
$44.22 / 2 = $22.11
$72.11 / 2 = $36.05
$72.11 / 3 = $24.03
$43.33 / 3 = $14.44

Testing: DC1 = DC1 + DC2
$44.22 += $44.22 -- after assignment: DC1=$88.44
$44.22 += $72.11 -- after assignment: DC1=$116.33
$44.22 += $43.33 -- after assignment: DC1=$87.55

Testing: DC1 = DC1 - DC2
$72.11 -= $44.22 -- after assignment: DC1=$27.89
$44.22 -= $43.33 -- after assignment: DC1=$0.89

Testing: DC1 = DC1 * int
$44.22 *= 2 -- after assignment: DC1= $88.44
$72.11 *= 2 -- after assignment: DC1= $144.22
$43.33 *= 2 -- after assignment: DC1= $86.66
$44.22 *= 3 -- after assignment: DC1= $132.66
$72.11 *= 3 -- after assignment: DC1= $216.33
$43.33 *= 3 -- after assignment: DC1= $129.99

Testing: DC1 = DC1 / int
$44.22 /= 2 -- after assignment: DC1= $22.11
$72.11 /= 2 -- after assignment: DC1= $36.05
$43.33 /= 2 -- after assignment: DC1= $21.66
$44.22 /= 3 -- after assignment: DC1= $14.74
$72.11 /= 3 -- after assignment: DC1= $24.03
$43.33 /= 3 -- after assignment: DC1= $14.44


I'm getting incorrect values for my operator- function and my operator/ operator* operator-= operator*= and operator/= most notably..
Topic archived. No new replies allowed.