0

So I've created this class which can add the two values of two objects. What I don't really understand is in the operator function, does the values of numerator and denominator come from the object no1 in int main()?

class frac
{
    public:
        frac operator+(frac&);
        frac();
        frac(int, int);
        int numerator;
        int denominator;
};

frac frac::operator+(frac& tmp)
{
    frac tmpResult;
    tmpResult.numerator = numerator + tmp.numerator;
    tmpResult.denominator = denominator + tmp.denominator;

    return tmpResult;
}

int main()
{
    frac no1(2, 5);
    frac no2(3, 6);
    frac result = no1 + no2;
    return 0;
}
Tobias Sundell
  • 117
  • 1
  • 6

6 Answers6

1

does the values of numerator and denominator come from the object no1 in int main()?

Yes.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

Yes, it is defined as a member function, so it is equivalent to call

no1.operator+(no2);

You want to change the parameter type to a const reference, as you don't really want to modify the right hand side. And you want to fix your math.

Note you could also use a free function

frac operator+(const frac& lhs, const frac& rhs) { ... }

which seems more natural to some people (including me).

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • Note to newbies: If `frac::numerator` and `frac::denominator` were `private`, the free function above would be declared as `friend`. – diegoperini Oct 02 '13 at 18:39
  • @diegoperini Better yet, declare a member function for `operator+=` and you don't need to make the free function `operator+` a friend. Or use a library like Boost.Operators or my df.operators (see my profile for link) to generate `operator+` from `operator+=`. – Daniel Frey Oct 02 '13 at 18:41
  • (No need to be friends ...) in fact you'd define the free function like this: `inline frac operator+(frac lhs, const frac& rhs) { lhs += rhs; return lhs; }` – moooeeeep Oct 02 '13 at 18:43
  • @moooeeeep That's not necessarily the most efficient way. That's why you use a library like df.operators :) – Daniel Frey Oct 02 '13 at 18:44
  • @DanielFrey of course there's a trade off between simplicity and efficiency. Mostly simplicity wins on this, I think. – moooeeeep Oct 02 '13 at 18:46
  • @moooeeeep `class frac : df::commutative_addable< frac > { ... };` sounds simple enough to me ;) – Daniel Frey Oct 02 '13 at 18:48
0

Yes, you are right. Class members can be accessed within class methods without specifying their origin (as if they are declared locally).

frac frac::operator+(frac& tmp)
{
    frac tmpResult;
    tmpResult.numerator = numerator + tmp.numerator;
    tmpResult.denominator = denominator + tmp.denominator;

    return tmpResult;
}

This code can be rewritten as this:

frac frac::operator+(frac& tmp)
{
    frac tmpResult;
    tmpResult.numerator = this->numerator + tmp.numerator;
    tmpResult.denominator = this->denominator + tmp.denominator;

    return tmpResult;
}

PS: I believe you meant operator overloading.

Edit: I had this urge to correct your math as you are dealing with fractions wrong.

Fraction addition (and substraction respectively) can be done like this:

frac frac::operator+(frac& tmp)
{
    int common_denominator = tmp.denominator * this->denominator;
    int common_numerator = tmp.numerator * this->denominator + this->numerator * tmp.denominator;

    //You can add simplification by dividing these 
    //two above with their greatest common divisor 
    //in order to avoid cases like 111/222 which can
    //be represented as 1/2. (this is optional)

    return frac(common_numerator, common_denominator)
}
diegoperini
  • 1,796
  • 21
  • 37
0

YES. Values of numerator and denominator come from Object no 1.

For your understanding, you can also write it as:

frac result = no1.operator+( no2 );
Shumail
  • 3,103
  • 4
  • 28
  • 35
0

Your main() could be rewritten to be more explicit:

int main()
{
    frac no1(2, 5);
    frac no2(3, 6);
    frac result = no1.operator+( no2 );
    return 0;
}

This code is equivalent, but could be easier to understand which object pointer passed as this into operator+

Slava
  • 43,454
  • 1
  • 47
  • 90
0

Ignoring your mathematical errors ...

When you declare an overloaded operator as a member function, the first parameter is assumed to be this. That is, no1 + no2 is just shorthand for no1.operator+(no2). Thus, the function sees numerator and denominator from the current no1 object (since it is on the left).

You could, alternatively, declare the function this way:

class frac
{
    // class declaration
    friend frac operator+(const frac& lhs, const frac& rhs);
};

frac operator+(const frac& lhs, const frac& rhs)
{
    // implement fraction addition for lhs + rhs
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42