face-sunglassesДружественные классы в C++

06.03.2025

Что это вообще?

Дружественный класс — это когда один класс говорит другому: "Бери мои секреты, ты в деле". В C++ есть private и protected штуки, которые обычно никто не трогает. Но если ты пишешь friend, то другому классу открывается доступ, как будто он свой.

Как это задать?

Пишешь friend class ИмяКласса; внутри того класса, чьи секреты отдаёшь. Всё, теперь этот "друг" может лезть куда угодно в твоём классе.

Код #1: База с коробкой

Вот простой пример, чтобы въехать:

#include <iostream>

class Box {
private:
    double width;  // Ширина — это секрет
public:
    Box(double w) {
        width = w;  // Задаём ширину
    }
    friend class Printer;  // Printer — наш бро, пускаем его
};

class Printer {
public:
    void printBox(Box b) {
        // Лезем в секретное поле width, потому что мы друзья
        std::cout << "Ширина коробки: " << b.width << std::endl;
    }
};

int main() {
    Box myBox(15.0);  // Коробка с шириной 15
    Printer myPrinter;  // Создаём принтер
    myPrinter.printBox(myBox);  // Вывод: Ширина коробки: 15
    return 0;
}

Тут Box пускает Printer к своей ширине. Без friend был бы облом — private никто не видит.

Код #2: Человек и доктор

Теперь пример, как будто из жизни:

Тут Doctor шарит за все приватные штуки Person, потому что он в друзьях.

Как это работает?

  1. Ты в классе (например, Box) пишешь friend class Printer;.

  2. Теперь Printer может в своих функциях обращаться к width, как будто это его поле.

  3. Но это работает только в одну сторону — Box не может лезть в Printer, если тот не скажет "ты тоже мой друг".

Код #3: Машина и механик

Ещё пример, чтобы закрепить:

Механик шарит за пробег, хотя он private, потому что он друг.

Код #4: Два класса с дружбой

А что если два класса помогают друг другу? Вот пример:

Тут Game видит score из Player, потому что он друг. Но Player не видит level, потому что дружба односторонняя.

Зачем это нужно?

  • Когда два класса как братья — один хранит данные, другой с ними работает. Например, список и его итератор.

  • Чтобы не писать кучу функций типа getScore() или getWidth(), а просто дать доступ.

Код #5: Альтернатива без дружбы

Для сравнения, вот как было бы без friend:

Без friend надо делать геттеры, а с friend — сразу доступ.

circle-info

Чего остерегаться?

  • Не делай всех подряд друзьями, а то потеряешь контроль над данными.

  • Если можно обойтись без friend (например, через геттеры), лучше так и сделать.

Last updated