Reputation: 499
I'm having trouble knowing what I'm doing wrong.
Huge& Huge::operator *=(const Huge& h) {
Huge retHuge = *this * h;
string out1 = retHuge.toString(); // for debugging purposes
return *this = retHuge;
// return retHuge;
}
The
Huge retHuge = *this * h;
works fine as I verify in the string out1
. If I return retHuge and print the result in the calling routine, I can see that the original this remains unchanged. If I do a *this = retHuge
and return *this
, I get a SEGSEGV
fault.
What is the proper way to call the destructor to clean up memory and to return the result after the multiply?
I would like to thank all of you for the answers. Crazy Eddie used what I had and extended it, which is exactly what I wanted to do. I changed the source to reflect his suggestion and the SEGSEGV fault comes up.
I take this to mean that my syntax must be basically correct but that I have a bug hidden in the rest of my code. This is valuable information and I need to go back and very carefully look to see if I can find something. I don't want to be lazy and ask for help before I do my homework properly, so I'll have a good look first.
My experience is mainly with Java which has a nice garbage collector for unreferenced objects. I'll go through with the debugger and verify that my destructor is being called to free the memory.
That was a good tip to try to do the *= operator first and then build the = operator from it. Clearly I did things in the opposite direction. Still your answers seem to indicate that what I did should indeed work. Since it doesn't work, I'll go back and see if I can find anything. If, after I have done my homework, I still can't find anything, I'll continue to ask. In the meantime, thanks for all the help.
Upvotes: 1
Views: 208
Reputation: 224119
The canonical form of overloading arithmetic operators applied to your specific case:
Huge& Huge::operator *=(const Huge& h) // class member function
{
// somehow multiply h's value into this' value
return *this;
}
Huge operator*(Huge lhs, const Huge& rhs) // free function; note lhs being copied
{
lhs *= rhs; // *= already implemented above
return lhs;
}
There is no dynamic memory involved here at all, hence you do not need to delete any.
The compound assignment form should be a member according to the operator overloading rules of thumb because it changes it's left-hand operand (and is likely to need access to the class' private parts). The non-assigning version should be a free member function so that implicit conversions can be applied equally to both operands.
Upvotes: 8
Reputation: 19347
Do not delete this
; afterwards, *this
is writing into unallocated memory.
Instead, just say *this = retHuge
(without delete this
), then return *this
.
Handle deallocation in operator =
instead.
Here's a complete-ish example, with an imaginary complicated payload of an int *
:
#include <iostream>
class A {
public:
A(int _val): val(new int(_val))
{ }
~A() {
delete this->val;
}
A &operator =(const A &r) {
// Pretend this->val is complex and we need to reallocate the
// entire thing.
delete this->val;
this->val = new int(*r.val);
return *this;
}
A operator *(const A &r) const {
return A(*this->val * *r.val);
}
A &operator *=(const A &r) {
return *this = *this * r;
}
int *val;
};
int main() {
A x(5), y(10);
x *= y;
std::cout << "x: " << *x.val << ", y: " << *y.val << std::endl;
return 0;
}
Upvotes: 1
Reputation: 40877
Since you seem to already have the * operator, and I'll assume at this point that assignment works, this would be the best implementation:
Huge& Huge::operator *=(const Huge& h) {
Huge retHuge = *this * h;
return *this = retHuge;
}
Upvotes: 1
Reputation: 49261
operator=
means you assign the right hand site into this.
So, you should change the contents of this, and then in the end return *this;
Upvotes: 0