Search code examples
c++operator-overloadingencapsulation

Class Data Encapsulation(private data) in operator overloading


Below is the code

The Code:

#include <iostream>
using namespace std;

class Rational {
  int num;  // numerator
  int den;  // denominator
  friend istream& operator>> (istream & , Rational&);
  friend ostream& operator<< (ostream &  , const Rational&);
 public:
  Rational (int num = 0, int den = 1)
    :     num(num), den(den) {}
  void getUserInput() {
    cout << "num = ";
    cin >> num;
    cout << "den = ";
    cin >> den;
  }
  Rational operator+(const Rational &);
};

Rational Rational::operator+ (const Rational& r) { //HERE 
  int n = num * r.den + den * r.num;
  int d = den * r.den;
  return Rational (n, d);
}

istream& operator>> (istream & is , Rational& r)
{
    is >> r.num >> r.den;
}

ostream& operator<< (ostream & os , const Rational& r)
{
    os << r.num << " / " <<  r.den << endl;;
}
int main() {
  Rational r1, r2, r3;
  cout << "Input r1:\n";
  cin >> r1;
  cout << "Input r2:\n";
  cin >> r2;
  r3 = r1 + r2;
  cout << "r1 = " << r1;
  cout << "r2 = " << r2;
  cout << "r1 + r2 = " << r3;
  return 0;
}

The Question

The above code has a operator+ overloading , in the operator+ definition we can see the parameter r accessing the private data (r.num and r.den) . Why C++ allow the parameter to access private data outside of the class ? Is it some kind of a special case?

Thank you.


Solution

  • Access specifiers apply at the level of classes, not instances, so the Rational class can see private data members of any other Rational instance. Since your Rational operator+ is a member function, it has access to private data of it's Rational argument.

    Note: the canonical approach is to define a member operator +=, and then use that to implement a non-member operator+

    struct Foo
    {
      int i;
    
      Foo& operator+=(const Foo& rhs) 
      { 
        i += rhs.i;
        return *this;
      }
    
    };
    
    Foo operator+(Foo lhs, const Foo& rhs)
    {
      return lhs += rhs;
    }