Класс Data Encapsulation (приватные данные) при перегрузке операторов

Ниже приведен код

Код:

#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;
}

Вопрос

В приведенном выше коде есть оператор + перегрузка, в определении оператора + мы можем видеть параметр r доступ к личным данным (r.num и r.den). Почему C ++ позволяет параметру получать доступ к частным данным вне класса? Это какой-то особый случай?

Спасибо.

1

Решение

Спецификаторы доступа применяются на уровне классов, а не экземпляров, поэтому Rational класс может видеть личные данные членов любого другого Rational пример. Так как ваш Rational operator+ является функцией-членом, она имеет доступ к частным данным своего Rational аргумент.

Примечание: канонический подход заключается в определении члена operator +=, а затем использовать это для реализации не члена 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;
}
3

Другие решения

Rational::operator+ является функцией-членом, поэтому она имеет доступ к все Члены каждый Rational объект.

Совет по кодированию: такие вещи обычно пишутся в двух частях: operator+= это член, и operator+ это не. Как это:

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;
}
1

Почему C ++ позволяет параметру получать доступ к частным данным вне класса? Это какой-то особый случай?

Правило со спецификаторами доступа:
«Спецификаторы доступа применяются для каждого класса, а не для каждого объекта»
Таким образом, вы всегда можете получить доступ private члены объекта класса в функции-члене этого класса.

Конструктор копирования / оператор присваивания копии — часто используемые примеры правила, хотя мы не замечаем это часто.

Онлайн образец:

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);
}

Хорошо для чтения:
Что такое спецификаторы доступа? Должен ли я наследовать с частным, защищенным или публичным?

1

В то время как другие плакаты объяснили как спецификатор доступа C ++ работает, никто не объяснил Зачем они работают таким образом.

Увеличение инкапсуляции это все о минимизировать количество кода который имеет доступ к внутренним объектам вашего объекта (т. е. вашим членам данных), а не к числу объектов. Если бы спецификаторы доступа ограничивали доступ к внутренним объектам других объектов в том же классе, это не увеличить инкапсуляцию.

Инкапсуляция важна, потому что это означает, что изменение деталей реализации повлияет на минимальный объем кода. Увеличение инкапсуляции увеличивает ремонтопригодность кода. Это время сборки, а не концепция времени исполнения.

1

Вопрос показывает недоразумение:
«Почему C ++ позволяет параметру получать доступ к частным данным вне класса?»

Оператор метода + принадлежит классу: он объявлен внутри класса, и в его реализации вы увидите, что метод является членом класса с префиксом имя_класса ::
Так что с оператором + нет доступа, если частные члены вне класса.

Операторы << и >> это другой случай — они действительно не принадлежат классу, так как они вызываются потоковым объектом. Вот почему их реализация не имеет префикса Rational ::.
Чтобы предоставить этим операторам доступ к закрытым данным объекта, они объявлены друзьями класса в объявлении класса. Объявляя функции или классы друзьями моего собственного класса, я показываю, что доверяю им не вмешиваться в личные данные моего класса.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector