0

The course I am taking says that returning this object reference (using *this) is mainly for chaining equal signs (For example: b = d = c = a) However, I cannot understand how this return works while I am overloading the '=' operator. Is it also necessary if I am not going to use any kind of chain? How does this return statement works? Thank you very much.

class Rational {

    int _n = 0; // '_n' stands for numerator
    int _d = 1; // '_d' stands for denominator

public:

    Rational (int numerator = 0, int denominator = 1) : _n(numerator), _d(denominator) {};
    Rational (const Rational & rhs) : _n(rhs._n), _d(rhs._dd) {};

    ~Rational ();

    int numerator() const { retrun _n; };
    int denominator() const { return _d; };

    Rational & operator = (const Rational &);
    Rational operator + (const Rational &) const;
    Rational operator - (const Rational &) const;
    Rational operator * (const Rational &) const;
    Rational operator / (const Rational &) const;
};

Rational & Rational::operator = (const Rational & rhs) {
    if(this != &rhs){
        _n = rhs.numerator();
        _d = rhs.denominator();
    }
    return *this;
}

Rational Rational::operator + (const Rational & rhs) const {
    return Rational((_n * rhs._d) + (_d * rhs._n), (_d * rhs._d));
}

Rational Rational::operator - (const Rational & rhs) const {
    return Rational((_n * rhs._d) + (_d * rhs._n), (_d * rhs._d));
}

Rational Rational::operator * (const Rational & rhs) const {
    return Rational((_n * rhs._n), (_d * rhs._d));
}

Rational Rational::operator / (const Rational & rhs) const {
    return Rational((_n * rhs._d), (_d * rhs._n));
}

Rational::~Rational(){
    print("dtor: %d/%d\n", this->_n, this->_d);
    _n = 0; _d = 1;
}

std::ostream & operator << (std::ostream & o, const Rational & r){
    return o << r.numerator() << "/" << r.denominator();
}

int main(int argc, char** argv){

    Rational a = 7;                 // 7/1              
    cout << "a is: " << a << endl;
    Rational b(5, 3);               // 5/3
    cout << "b is: " << b << endl;
    Rational c = b;                 // Copy constructor
    cout << "c is: " << c << endl;
    Rational d;                     // Default constructor
    cout << "d is: " << d << endl;
    d = c;                          // Assignment constructor
    cout << "d is: " << d << endl;
    Rational & e = d;               // Reference
    d = e;                          // Assignment to self!
    cout << "e is: " << e << endl;

    cout << a << " + " << b << " = " << a + b << endl;
    cout << a << " - " << b << " = " << a - b << endl;
    cout << a << " * " << b << " = " << a * b << endl;
    cout << a << " / " << b << " = " << a / b << endl;

    return 0;
}
François Andrieux
  • 28,148
  • 6
  • 56
  • 87
maufcost
  • 169
  • 11
  • Sorry for the ` multiple times. I am new at Stack Over Flow. – maufcost Feb 21 '18 at 20:01
  • 1
    It does not have to. Doing so is idiomatic in the language, but not doing it (for example, having the return type be `void` instead) will cause the compiler to emit an error if it is used like `a = b = c`. – Eljay Feb 21 '18 at 20:16

1 Answers1

0

Let's say we make two Rational to demonstrate.

Rational r1(1,2), r2(2,3);

r1 = r2;

When we do this, first r1 will be made equal to r2. Then the operation will return r1. Just like any function call we can choose to ignore the return value if we want.

On the other hand we could also choose to not ignore it.

Rational r1(1,2), r2(2,3), r3;

r3 = (r1 = r2);

The parenthesis to emphasize the fact that first r1 = r2, that will return r1. Next r3 = r1.

It is the same principle as if you where using functions.

#include <iostream>

int print(int x) {
    std::cout << x << std::endl;
    return x;
}

void increase(int x) {
    std::cout << x + 5 << std::endl;
}

int main() {
    print(5); // We can ignore the return value, and just print the number

    int x = print(7); // We can print the number and store the value in a variable

    increase(print(3));  // We can print the value and pass it on to the increase function

    return 0;
}
super
  • 12,335
  • 2
  • 19
  • 29
  • I undertood your point. So, is it basically unnecessay to return the object reference in this function? – maufcost Feb 21 '18 at 21:10
  • @MauriceFigueiredo It is only necessary if you want to use the return value. However, for a `operator=` most people will expect it as it is the standard way of doing it in c++. – super Feb 21 '18 at 21:14
  • Great! Now I got it completely. – maufcost Feb 21 '18 at 21:30