Дружественные классы — понятие, схожее с дружественными функциями. Ключевое отличие: объявление класса другом другого класса делает все его функции дружественными для класса-хозяина.
Демонстрация работы дружественных классов
Создадим классы Dog и Person.
Класс Dog содержит переменную health типа int, инициализированную значением 100:
class Dog {
public:
int health = 100;
};
Класс Person содержит функции damage (уменьшает health объекта Dog) и heal (увеличивает health):
class Person {
public:
void damage(Dog& d) {
d.health -= 20;
}
void heal(Dog& d) {
d.health += 30;
}
};
Использование ссылки Dog& d в функциях важно для изменения значения health исходного объекта, а не его копии.
Объявление дружественного класса
Чтобы Person мог получать доступ к приватным членам Dog, объявим Person дружественным классом для Dog:
class Dog {
public:
int health = 100;
friend class Person; // Объявление Person дружественным классом
};
class Person {
public:
void damage(Dog& d) { d.health -= 20; }
void heal(Dog& d) { d.health += 30; }
};
Важно: если Person объявлен перед Dog, перед объявлением Dog потребуется добавить class Person; для корректной компиляции.
Использование дружественных классов
Создадим объекты:
Dog scubi;
Person volodia;
Используем damage для изменения health объекта scubi:
volodia.damage(scubi);
std::cout << scubi.health << std::endl; // Выведет 80
Аналогично, используем heal:
volodia.heal(scubi);
std::cout << scubi.health << std::endl;
Преимущества дружественных классов
Дружественные классы предпочтительнее множества дружественных функций при многостороннем взаимодействии классов. В примере, вместо двух отдельных дружественных функций (для уменьшения и увеличения здоровья), используется один дружественный класс с двумя методами. Это улучшает организацию и поддержку кода.
Работа со ссылками
Передача объекта по значению не изменяет исходный объект. Для изменения health исходного объекта Dog используются ссылки (&). Без ссылок, изменения health внутри функции были бы локальными.
Дружественные классы — мощный инструмент в C++, обеспечивающий контролируемый доступ к приватным членам класса из другого класса. Они упрощают взаимодействие между классами, повышая читаемость и поддерживаемость кода. Правильное использование ссылок гарантирует корректное изменение значений исходных объектов.