💀
Второй курс РПО
C++
C++
  • Свойства и типы
  • Блок-схемы
  • Visual Studio
  • Первый проект
  • Вывод данных
  • Типы данных
  • Переменные и Константы
  • Ввод данных
  • Литералы
  • Задание [ ! ]
  • Первая практическая
  • Операторы в языке программирования
  • Арифметические операции в C++
  • Применение арифметических операций
  • Практическая работа №2
  • Практическая работа №3
  • Логические операции
    • Справочник по командам
  • Практическая работа №4
  • Практическая работа №5
  • Массивы
    • Спец. задание
  • ⚙️Справочник по C++
  • Домашнее задание №1
  • Функции
    • Более краткая версия
  • Практическая работа №6
  • Указатели
  • Задание на экране 12.12
  • Введение в строки
  • Перегрузка функций в C++
  • Функции класса
  • Полезные штуки
  • Работа с классами в C++
  • Дружественные классы в C++
Powered by GitBook
On this page
  • Что это вообще?
  • Как это задать?
  • Код #1: База с коробкой
  • Код #2: Человек и доктор
  • Как это работает?
  • Код #3: Машина и механик
  • Код #4: Два класса с дружбой
  • Зачем это нужно?
  • Код #5: Альтернатива без дружбы

Дружественные классы в 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: Человек и доктор

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

#include <iostream>

class Person {
private:
    int weight;  // Вес — личное дело
    int age;    // Возраст тоже секрет
public:
    Person(int w, int a) {
        weight = w;
        age = a;
    }
    friend class Doctor;  // Доктору можно всё знать
};

class Doctor {
public:
    void checkPerson(Person p) {
        // Доктор шарит и за вес, и за возраст
        std::cout << "Вес: " << p.weight << " кг, возраст: " << p.age << " лет" << std::endl;
    }
};

int main() {
    Person me(75, 25);  // Я вешу 75 кг, мне 25
    Doctor doc;         // Доктор на связи
    doc.checkPerson(me);  // Вывод: Вес: 75 кг, возраст: 25 лет
    return 0;
}

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

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

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

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

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

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

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

#include <iostream>

class Car {
private:
    int mileage;  // Пробег — секретный
public:
    Car(int m) {
        mileage = m;
    }
    friend class Mechanic;  // Механик в деле
};

class Mechanic {
public:
    void fixCar(Car c) {
        // Механик видит пробег и чинит
        std::cout << "Пробег машины: " << c.mileage << " км" << std::endl;
        // Допустим, чинит что-то
    }
};

int main() {
    Car myCar(50000);  // Машина с пробегом 50к
    Mechanic pro;      // Механик готов
    pro.fixCar(myCar);  // Вывод: Пробег машины: 50000 км
    return 0;
}

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

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

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

#include <iostream>

class Player {
private:
    int score;  // Очки игрока
public:
    Player(int s) {
        score = s;
    }
    friend class Game;  // Game — наш кореш
};

class Game {
private:
    int level;  // Уровень игры
public:
    Game(int l) {
        level = l;
    }
    void showStats(Player p) {
        // Game видит очки игрока
        std::cout << "Уровень: " << level << ", Очки: " << p.score << std::endl;
    }
};

int main() {
    Player me(100);  // У меня 100 очков
    Game myGame(5);  // Игра на 5 уровне
    myGame.showStats(me);  // Вывод: Уровень: 5, Очки: 100
    return 0;
}

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

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

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

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

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

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

#include <iostream>

class Box {
private:
    double width;
public:
    Box(double w) {
        width = w;
    }
    double getWidth() {  // Пришлось бы писать геттер
        return width;
    }
};

class Printer {
public:
    void printBox(Box b) {
        std::cout << "Ширина коробки: " << b.getWidth() << std::endl;
    }
};

int main() {
    Box myBox(15.0);
    Printer myPrinter;
    myPrinter.printBox(myBox);  // Всё ещё работает, но больше кода
    return 0;
}

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

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

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

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

PreviousРабота с классами в C++

Last updated 2 months ago