В этом уроке мы изучим создание дружественных классов в C++.
В предыдущем уроке мы познакомились с дружественными функциями. Теперь рассмотрим дружественные классы. Они аналогичны дружественным функциям, но предоставляют доступ к приватным членам класса не только одной функции, а всему другому классу.
Классы Dog и Person
Продемонстрируем это на примере класса Dog, описывающего собаку, и класса Person, описывающего человека.
Класс Dog
class Dog {
private:
int Health = 100; // Уровень здоровья
};
Класс Dog содержит поле Health — уровень здоровья собаки (изначально 100).
Класс Person
class Person {
public:
void damage(Dog& dog) {
dog.Health -= 20;
std::cout << "Health of Animal: " << dog.Health << std::endl;
}
void heal(Dog& dog) {
dog.Health += 10;
std::cout << "Health of Animal: " << dog.Health << std::endl;
}
void kill(Dog& dog) {
dog.Health = 0;
std::cout << "Health of Animal: " << dog.Health << std::endl;
}
};
Класс Person содержит методы damage (наносит урон), heal (восстанавливает здоровье) и kill (убивает собаку). Каждый метод обращается к полю Health класса Dog. Без объявления дружественного класса, обращение к dog.Health вызовет ошибку компиляции, поскольку Health — приватный член класса Dog.
Объявление дружественного класса
Чтобы предоставить классу Person доступ к приватным членам класса Dog, объявим Person дружественным классом для Dog:
class Dog {
private:
int Health = 100;
friend class Person; // Объявление Person как дружественного класса
};
Строка friend class Person; внутри определения класса Dog делает весь класс Person дружественным. Теперь методы класса Person могут обращаться к приватным членам класса Dog без ошибок.
Важно: Для корректной работы кода необходимо объявить прототип класса Person перед определением класса Dog, если класс Person объявлен после Dog. Это предотвратит ошибку компиляции, поскольку компилятор должен знать о существовании класса Person перед его использованием в объявлении дружественного класса.
Тестирование кода
Создадим объекты классов Dog и Person и протестируем методы:
int main() {
Dog Scooby;
Person Alex;
Alex.damage(Scooby);
Alex.damage(Scooby);
Alex.heal(Scooby);
Alex.heal(Scooby);
Alex.kill(Scooby);
return 0;
}
Этот код демонстрирует использование методов класса Person для изменения уровня здоровья объекта Scooby класса Dog.
Использование дружественных классов позволяет обеспечить доступ к приватным членам одного класса из другого, что полезно для реализации сложных взаимодействий. Однако, следует использовать эту возможность с осторожностью, так как чрезмерное использование может нарушить инкапсуляцию и усложнить поддержку кода.