Почему == перегрузка может получить доступ к закрытым членам аргумента

Возможный дубликат:
почему частное значение объекта obj может быть изменено экземпляром класса?

Рассмотрим следующий (частичный) код:

class Group {
private:
int id;

public:
void set_id(int);
int get_id();
bool operator==(const Group&);
};bool Group::operator==(const Group& g) {
if(g.id == this->id) {  /* id is private? */
return true;
}

return false;
}

Код компилируется и результаты кажутся правильными. Однако в if часть реализации перегрузки оператора, мы непосредственно обращаемся к закрытому члену его аргумента — const Group& g, но не является ли такой доступ недействительным?

6

Решение

Ваш operator== является членом вашего Group учебный класс. Функции-члены могут получить доступ к любому private Члены этого класса, не только для this, но для любого экземпляра они могут получить доступ.

Если вы думаете об этом, такое поведение необходимо, потому что в противном случае контроль доступа создаст методы для взаимодействия двух или более экземпляров (swapКопировать конструкторы, операторы) невозможно, если только у объекта нет общедоступного метода доступа к какой-либо переменной-члену, которая используется в таком методе. Довольно часто это нежелательно с точки зрения дизайна. Кроме того, это подняло бы планку контроля доступа на высокий уровень («если я просто сделаю этого участника публичным, я избавлю меня от боли …»).

Заключение этого кода совершенно правильно (хотя я не понимаю, почему if необходимо, по сравнению с простым использованием return g.id == this->id;)

16

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

Спецификаторы доступа не контролируют доступ на уровне экземпляра, но на уровне типа. Любая функция-член экземпляра типа T может получить доступ ко всем закрытым членам любого другого экземпляра того же типа T.

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

13

Нет потому что operator== является членом Group, Это прямо в названии функции. Это означает, что он может получить доступ к private Члены любой объект этого класса.

Если бы вы попытались написать его как свободную функцию, это не скомпилировало бы:

bool areEqual(const Group& g1, const Group& g2) {
return g1.id == g2.id;
}
5