operator ++ overload - How To

J

JohnGoogle

Hi all,

For my own educational process I am implementing a Fraction class
described in the VSJ magazine to help me understand Visual C# operator
overloading. I'm a relative newbie.

At the moment my basic code is:


using System;
using System.Collections.Generic;
using System.Text;

namespace XYZ.Common
{

//
// This class is to demonstrate how to overload operators such as
+, -, ++.
//

public class Fraction
{
private Int32 numerator;
private Int32 denominator;

// Constructors

// 'Whole numbers'

public Fraction(Int32 numerator)
{
this.numerator = numerator;
this.denominator = 1;
}

// 'True fractions'

public Fraction(Int32 numerator, Int32 denominator)
{
this.numerator = numerator;
this.denominator = denominator;
}

// Implementation of the + operator

public static Fraction operator+(Fraction lhs, Fraction rhs)
{
if (lhs.denominator == rhs.denominator)
{
return new Fraction(lhs.numerator + rhs.numerator,
lhs.denominator);
}
else
{
Int32 denominator = lhs.denominator * rhs.denominator;
Int32 firstProduct = (denominator / lhs.denominator) *
lhs.numerator;
Int32 secondProduct = (denominator / rhs.denominator) *
rhs.numerator;

return new Fraction(firstProduct + secondProduct,
denominator);
}
}

// Implementation of the ++ operator - VERSION 1

public static Fraction operator ++(Fraction f)
{
f.numerator++;
return f;
}

// Implementation of the ++ operator - VERSION 2

public static Fraction operator ++(Fraction f)
{
return new Fraction(f.numerator + 1, f.denominator);
}

public override string ToString()
{
return numerator.ToString() + "/" + denominator.ToString();
}

}
}


My problem is that both versions of the operator ++ method compile and
return the correct result.

Version 1 simply returns the original object after amending it. Version
2 creates and returns a totally new object.


Which is the correct version to use with regard to memory allocation
etc?

Thanks for any help.
 
P

Paul E Collins

// Implementation of the ++ operator - VERSION 1
public static Fraction operator ++(Fraction f)
{
f.numerator++;
return f;
}
// Implementation of the ++ operator - VERSION 2
public static Fraction operator ++(Fraction f)
{
return new Fraction(f.numerator + 1, f.denominator);
}

As you've discovered, they both work correctly.

I'd strongly favour version 1, because (i) it doesn't have the
overhead (however small) of creating a new object and performing that
constructor call, and (ii) in the event that you add more fields to
the class, version 1 won't reset the other fields like version 2
would.

Memory management isn't an issue when you're only dealing with simple
Int32 variables.

Eq.
 
J

Jon Skeet [C# MVP]

Paul E Collins said:
As you've discovered, they both work correctly.

I'd strongly favour version 1, because (i) it doesn't have the
overhead (however small) of creating a new object and performing that
constructor call, and (ii) in the event that you add more fields to
the class, version 1 won't reset the other fields like version 2
would.

But the fact that it doesn't create a new object is the problem with it
as well. It means that after:

Fraction f = ....;
Fraction g = f;

then

f++;

isn't the same as:

f = f+1;

Now, quite possibly the class should actually be a struct, but if it
*does* need to be a class, I'd favour making it an immutable one, like
string.
 
B

Ben Newsam

But the fact that it doesn't create a new object is the problem with it
as well. It means that after:

Fraction f = ....;
Fraction g = f;

then

f++;

isn't the same as:

f = f+1;

Correct me if I'm wrong, but surely to add 1 to a fraction, you should
add the denominator into the numerator, not merely increment the
numerator? If your ++ operator did that, then f++ and f = f + 1 would
be the same.
 
J

Jon Skeet [C# MVP]

Ben Newsam said:
Correct me if I'm wrong, but surely to add 1 to a fraction, you should
add the denominator into the numerator, not merely increment the
numerator? If your ++ operator did that, then f++ and f = f + 1 would
be the same.

Leaving the actual addition to one side, the difference is that the
addition operator given returns a *new* object, leaving the old one
with the previous value - whereas the ++ operator given *changes* the
existing value.

But you're quite right - the ++ implementation should increment the
numerator by the denominator, not by one. At least, I'd be surprised by
the results of the current implementation.
 
J

JohnGoogle

Quite right about adding the denominator. Thanks. I didn't think it
through!

I think I'll go with version 1.

John.
 
J

JohnGoogle

Quite right about adding the denominator. Thanks. I didn't think it
through!

I think I'll go with version 1.

John.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top