Below is the code
The Code:
#include
using namespace std;
class Rational {
int num; // numerator
int den; // den
The question reveals a misunderstanding: "Why C++ allow the parameter to access private data outside of the class ?"
The method operator+ does belong to the class: it is declared within the class and in its implementation you'll see that the method is a member of the class by the prefix class_name:: So with operator+ there is no access if private members outside of the class.
The operators << and >> are a different case - these really do not belong to the class, since they are called by a stream object. That's why their implementation doesn't have the prefix Rational::. To allow these operators the access to private data of the object they are declared to be friends of the class within the class declaration. By declaring functions or classes to be friend of my own class I show that I trust them not to tamper with the private data of my class.
While the other posters have explained how the C++ access specifier work, no one has explained why they work in this way.
Increasing encapsulation is all about minimizing the amount of code which has access to your object internals (i.e. your data members), not the number of objects. If the access specifiers limited access to the internals of other objects within the same class, this would not increase encapsulation.
Encapsulation is important because it means that changing implementation details will affect a minimal amount of code. Increasing encapsulation increases the maintainability of code. It is a build-time, not a runtime concept.
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;
}
Why C++ allow the parameter to access private data outside of the class ? Is it some kind of a special case?
The rule with access specifiers is:
"Access specifiers apply to per class and not per object"
So, You can always access private
members of a class object in member function of that class.
A copy constructor/copy assignment operator are commonly used examples of the rule though we do not notice it that often.
Online Sample:
class Myclass
{
int i;
public:
Myclass(){}
Myclass(Myclass const &obj3)
{
//Note i is private member but still accessible
this->i = obj3.i;
}
};
int main()
{
Myclass obj;
Myclass obj2(obj);
}
Good Read:
What are access specifiers? Should I inherit with private, protected or public?
Rational::operator+
is a member function, so it has access to all members of every Rational
object.
Coding tip: this kind of things is usually written in two parts: an operator+=
that's a member, and an operator+
that's not. Like this:
Rational& Rational::operator+=(const Rational& rhs) {
num = num * rhs.den + den * rhs.num;
den *= rhs.den;
return *this;
}
Rational operator+(const Rational& lhs, const Rational& rhs) {
Rational result(lhs);
result += rhs;
return result;
}