Кафедра ИСиТ УО ВГТУ
  • Специальности
    • Экономика электронного бизнеса
    • Информационные системы
    • Information Control Systems
  • Каталог
  • Сайт кафедры
  • Сервисы
    • GitLab
    • JupyterHub
    • Soft
  1. ИСиТ
  2. ПСП
  3. Практика
  4. Лаб. работа “Структурные механизмы языка программирования для реализации полиморфизма в программах”
  • ИСиТ
    • АОС
      • Теория
        • Введение в операционные системы
        • Управление памятью
        • Управление процессами
        • Система ввода-вывода
        • Информационная безопасность
        • Виртуализация
      • Слайды
      • Практика
    • РВПсИПП
      • Теория
        • Настройка среды разработки для PHP
        • Введение в PHP
        • Работа с базами данных в PHP
        • Объектно-ориентированные возможности PHP
        • Разработка web-приложений на базе фреймворков
        • Основы Laravel
        • Шаблоны в Laravel
        • Модели и базы данных в Laravel
        • Формы и валидация в Laravel
        • Аутентификация и авторизация в Laravel
        • Создание REST API в Laravel
        • Работа с файлами и изображениями в Laravel
        • Тестирование и отладка в Laravel
        • Введение в фреймворк Symfony
        • Маршруты и контроллеры в Symfony
        • Шаблоны и Twig в Symfony
        • Формы и валидация в Symfony
        • Доступ к базам данных в Symfony
        • Аутентификация и авторизация в Symfony
        • Сервисы и зависимости в Symfony
        • Создание REST API в Symfony
        • Работа с файлами и медиа в Symfony
        • Сравнение и выбор фреймворка
        • Развертывание веб-приложения
      • Практика
        • Регистрация в JupyterHub
        • Лаб. работа “Основы PHP”
        • Лаб. работа “Массивы в PHP”
        • Лаб. работа “Создание веб-приложений с использованием Slim”
        • Лаб. работа 1 “Создание нового приложения Laravel”
        • Лаб. работа 2 “Добавление главной страницы и базовых маршрутов”
        • Лаб. работа 3 “Создание моделей, миграций и сидеров”
        • Лаб. работа 4 “Создание индексных страниц и пагинация”
        • Лаб. работа 5 “Создание форм для работы с сущностями”
        • Лаб. работа 6 “Работа с файлами (эмуляция S3-хранилища)”
        • Лаб. работа “Создание маршрутов в Laravel”
        • Лаб. работа “Работа с базами данных в Laravel”
        • Лаб. работа “Работа с формами в Laravel”
        • Лаб. работа “Аутентификация и авторизация в Laravel”
        • Лаб. работа “Работа с файлами в Laravel”
        • Лаб. работа “Тестирование и оптимизация в Laravel”
        • Лаб. работа “Создание REST API в Laravel”
        • Лаб. работа “Основы Symfony”
        • Лаб. работа “Шаблоны и представления в Symfony”
        • Лаб. работа “Работа с базами данных в Symfony”
        • Лаб. работа “Формы и аутентификация в Symfony”
        • Лаб. работа “Сервисы и зависимости в Symfony”
        • Лаб. работа “REST API в Symfony”
        • Лаб. работа “Работа с медиа контентом в Symfony”
        • Лаб. работа “Создание и развертывание проекта”
        • Расчетно-графическая работа: Разработка веб-приложения с использованием Laravel
          • Методические рекомендации по выполнению работы
          • Варианты заданий для расчетно-графической работы
    • ПСП
      • Теория
        • Введение
        • Протокол HTTP
        • Программирование с использованием сокетов
      • Практика
        • Программное обеспечение
        • Лаб. работа “Почтовые протоколы”
        • Лаб. работа “Протокол FTP”
        • Лаб. работа “Протокол HTTP”
        • Лаб. работа “Программирование сетевых приложений с использованием сокетов”
        • Лаб. работа “Обзор базовых конструкций и основных элементов языка”
        • Лаб. работа “Структурные элементы класса, методы взаимодействия объектов и организация наследования”
        • Лаб. работа “Типы исключительных ситуаций и процесс их обработки”
        • Лаб. работа “Потоки ввода/вывода и работа с файлами”
        • Лаб. работа “Организация потоков, параллельной обработки, синхронизации и распределённой обработки синхронизуемых участков кода”
        • Лаб. работа “Структурные механизмы языка программирования для реализации полиморфизма в программах”
        • Лаб. работа “Средства языка для организации работы в сети. Основные классы и интерфейсы реализации сетевого взаимодействия”
        • Лаб. работа “Библиотеки и средства внедрения визуальных компонент для организации GUI-интерфейсов пользователя. Обработка событий”
        • Лаб. работа “Концепция распределённой обработки данных и технологии удалённой обработки данных”
      • Темы курсовых проектов по дисциплине “Программирование сетевых приложений”
    • Компьютерные сети
      • Теория
        • Введение в компьютерные сети
        • Топологии сетей
        • Кодирование и мультиплексирование
        • Стеки протоколов
        • Адресация в компьютерных сетях
        • Система доменных имен (DNS)
        • Программирование с использованием сокетов
        • Введение в PHP
        • Протокол HTTP
        • Введение в компьютерные сети
      • Практика
        • Программное обеспечение
        • Регистрация в JupyterHub
        • Лаб. работа “Почтовые протоколы”
        • Лаб. работа “Протокол FTP”
        • Лаб. работа “Протокол HTTP”
        • Лаб. работа “Программирование сетевых приложений с использованием сокетов”
        • Лаб. работа “Основы PHP”
        • Лаб работа “Массивы в PHP”
    • РиОИИС
      • Слайды
      • Теория
        • Классификация оптимизационных задач
        • Генетические алгоритмы
        • Системы массового обслуживания
        • Теория игр
        • Машинное обучение
        • Глубокое обучение (Deep learning)
        • Основы функционального программирования
        • Основы программирования на Haskell
        • Введение в логическое программирование
        • Инференция и рассуждения в логическом программировании
        • Разработка экспертных систем
        • Интеллектуальные системы и их архитектура
        • Веб-скрэйпинг
        • Сбор данных с открытых API
      • Практика
        • JupyterHub
        • Лаб. работа “Основы программирования на Python”
        • Лаб. работа “Функции в Python”
        • Лаб. работа “Рекурсия в Python”
        • Лаб. работа “Итераторы в Python”
        • Лаб. работа “Методы одномерной оптимизации”
        • Лаб. работа “Методы многомерной оптимизации”
        • Лаб. работа “Линейное программирование”
        • Лаб. работа “Генетические алгоритмы”
        • Лаб. работа “Haskell”
        • Лаб. работа “Логическое программирование”
        • Лаб. работа “Сбор данных с помощью веб-скрейпинга”
        • Лаб. работа “Предобработка данных”
        • Лаб. работа “Машинное обучение: классификация”
        • Лаб. работа “Создание и обучение простейших нейронных сетей”
        • Лаб. работа “Системы массового обслуживания”
        • Лаб. работа “Обработка естественного языка”
        • Лаб. работа “Компьютерное зрение”
        • Лаб. работа “Нейросети и глубокое обучение”
    • КСКР
      • Практика
        • Лаб. работа “Одномерные и двумерные массивы в C#”
        • Лаб. работа “Обращение матриц в C#”
    • Системное программирование
      • Слайды
      • Слайды
      • Теория
        • Управление памятью в Windows
        • Файловые операции в Windows
        • Управление процессами в Windows
        • Графический интерфейс Windows
        • ОС Unix
      • Практика
        • Лаб. работа “Работа с динамической памятью в Windows”
        • Лаб. работа “Операции с файлами в Windows”
        • Лаб. работа “Управление процессами в Windows”
        • Лаб. работа “Работа с виртуальной машиной Linux”
        • Лаб. работа “Язык командного энтерпритатора Shell”
        • Лаб. работа “Работа с файлами в Linux”
        • Лаб. работа “Работа с процессами в Linux”
    • ИППРПО
      • Теория
      • Практика
        • Лаб. работа “Язык командного энтерпритатора Shell”
        • Лаб. работа “Управление процессами в Shell”
        • Лаб. работа “Управление файловой системой в Shell”
        • Лаб. работа “Управление пакетами в ОС Linux”
        • Лаб. работа “Сетевые инструменты в Linux”
        • Лаб. работа “Мониторинг и анализ системы Linux”
        • Лаб. работа “Основы Docker. Управление контейнерами”
        • Лаб. работа “Docker: Сети”
        • Лаб. работа "Docker: Образы"
        • Лаб. работа “Docker Compose: Управление многоконтейнерными приложениями”
        • Лаб. работа “CI/CD с GitLab”

Содержание

  • Цель работы
  • Теоретические сведения
    • Виртуальные функции
    • Чисто виртуальные функции и абстрактные классы
    • Переопределение (override)
    • Полиморфный вызов через указатель
    • Виртуальный деструктор
  • Задание для выполнения
    • Требования к программе
    • Пример ожидаемого вывода
  • Индивидуальные задания
    • Вариант 1. FTP-команды
    • Вариант 2. HTTP-команды
    • Вариант 3. HTTP-команды
    • Вариант 4. SMTP-команды
    • Вариант 5. DNS-команды
    • Вариант 6. SSH-команды
    • Вариант 7. Команды управления IoT
    • Вариант 8. Команды мониторинга
    • Вариант 9. Команды управления контейнерами
    • Вариант 10. Команды балансировщика
    • Вариант 11. Команды фаервола
    • Вариант 12. Команды базы данных
    • Вариант 13. Команды чата
    • Вариант 14. Команды VPN
    • Вариант 15. Команды файлового сервера
    • Вариант 16. Команды аутентификации
    • Вариант 17. Команды кэша
    • Вариант 18. Команды очереди сообщений
    • Вариант 19. Команды резервного копирования
    • Вариант 20. Команды CI/CD
  • Порядок выполнения
  • Контрольные вопросы
  • Содержание отчёта
  1. ИСиТ
  2. ПСП
  3. Практика
  4. Лаб. работа “Структурные механизмы языка программирования для реализации полиморфизма в программах”

Лаб. работа “Структурные механизмы языка программирования для реализации полиморфизма в программах”

Программирование сетевых приложений
Практика
Автор

Бизюк Андрей

Дата публикации

9 апреля 2026 г.

Цель работы

Изучить механизм виртуальных функций и переопределения методов. Разработать иерархию классов для представления сетевых команд с полиморфным выполнением через единый интерфейс.

Теоретические сведения

Виртуальные функции

Виртуальная функция — функция базового класса, которая может быть переопределена в производных классах. Вызов виртуальной функции через указатель на базовый класс приводит к вызову версии функции того объекта, на который указатель фактически ссылается.

class AbstractCommand {
public:
    virtual void execute() = 0;        // чисто виртуальная
    virtual ~AbstractCommand() = default; // виртуальный деструктор
};

Чисто виртуальные функции и абстрактные классы

Чисто виртуальная функция обозначается = 0. Класс, содержащий хотя бы одну чисто виртуальную функцию, является абстрактным — нельзя создать его объект.

class AbstractCommand {
public:
    virtual void execute() = 0;
    virtual string getName() const = 0;
    virtual ~AbstractCommand() = default;
};

Переопределение (override)

Ключевое слово override проверяет, что функция действительно переопределяет виртуальную функцию базового класса:

class LoginCommand : public AbstractCommand {
public:
    void execute() override { /* реализация */ }
    string getName() const override { return "LOGIN"; }
};

Полиморфный вызов через указатель

vector<AbstractCommand*> commands;
commands.push_back(new LoginCommand("admin", "12345"));
commands.push_back(new SendCommand("Hello"));
commands.push_back(new DisconnectCommand());

for (auto* cmd : commands) {
    cmd->execute();    // полиморфный вызов
    delete cmd;
}

Виртуальный деструктор

Без виртуального деструктора при delete через указатель на базовый класс вызывается только деструктор базового класса, а не производного — утечка ресурсов.

// БЕЗ virtual: вызывается только ~AbstractCommand()
// С virtual: вызывается ~LoginCommand(), затем ~AbstractCommand()
AbstractCommand* cmd = new LoginCommand();
delete cmd;

Задание для выполнения

Разработать иерархию классов для представления сетевых команд с использованием виртуальных функций. Реализовать обработчик, который принимает массив указателей на базовый класс и полиморфно выполняет каждую команду.

Требования к программе

  1. Создать абстрактный базовый класс AbstractCommand:

    • защищённые поля: timestamp (string), status (string, по умолчанию "pending")
    • чисто виртуальные методы: void execute(), string getName() const, string getDescription() const
    • открытые методы: string getStatus() const, string getTimestamp() const
    • виртуальный деструктор
  2. Создать производные классы:

    • LoginCommand — аутентификация на сервере
      • поля: username, password (string)
      • execute(): проверяет длину пароля (≥ 6), если успешно — status = "OK", иначе — status = "FAILED: invalid password". Выводит: [LOGIN] Попытка входа: <username> → <status>
    • SendCommand — отправка данных
      • поля: recipient (string), data (string), dataSize (int, вычисляется в конструкторе)
      • execute(): если data не пустое и recipient не пустой — status = "OK", иначе — status = "FAILED: empty data or recipient". Выводит: [SEND] → <recipient> (<dataSize> байт) → <status>
    • ReceiveCommand — получение данных
      • поля: sender (string), buffer (string, заполняется при выполнении)
      • execute(): генерирует случайное сообщение от sender. status = "OK". Выводит: [RECV] ← <sender>: <buffer> → <status>
    • DisconnectCommand — отключение от сервера
      • поля: reason (string)
      • execute(): status = "OK". Выводит: [DISCONNECT] Причина: <reason> → <status>
    • PingCommand — проверка доступности
      • поля: targetHost (string), rtt (int, генерируется случайно 1–100 мс)
      • execute(): status = "OK". Выводит: [PING] <targetHost> — RTT: <rtt>мс → <status>
    • StatusCommand — запрос статуса сервера
      • поля: serverInfo (string, заполняется при выполнении)
      • execute(): генерирует информацию о сервере (имитация). status = "OK". Выводит: [STATUS] <serverInfo> → <status>
  3. Создать класс CommandHandler:

    • поле: vector<AbstractCommand*> history
    • метод addCommand(AbstractCommand* cmd) — добавляет команду в историю
    • метод executeAll() — полиморфно выполняет все команды из истории
    • метод showHistory() — выводит все выполненные команды с их статусами
    • метод showSuccessful() — выводит только команды со статусом "OK"
    • метод clearHistory() — удаляет все команды из истории (с освобождением памяти)
  4. В функции main():

    • Создать объект CommandHandler
    • Добавить команды всех типов с различными параметрами
    • Выполнить все команды через executeAll()
    • Вывести полную историю
    • Вывести только успешные команды
    • Очистить историю

Пример ожидаемого вывода

=== Выполнение команд ===
[LOGIN] Попытка входа: admin → OK
[SEND] → user@192.168.1.5 (13 байт) → OK
[RECV] ← server@10.0.0.1: ACK received → OK
[DISCONNECT] Причина: user request → OK
[PING] 192.168.1.1 — RTT: 23мс → OK
[STATUS] Сервер: online, клиенты: 5, нагрузка: 32% → OK
[LOGIN] Попытка входа: guest → FAILED: invalid password
[SEND] →  (0 байт) → FAILED: empty data or recipient

=== История выполнения (8 команд) ===
1. [LOGIN]    admin       → OK
2. [SEND]     user@...    → OK
3. [RECV]     server@...  → OK
4. [DISCONNECT] user req   → OK
5. [PING]     192.168.1.1 → OK
6. [STATUS]   online      → OK
7. [LOGIN]    guest       → FAILED: invalid password
8. [SEND]     (empty)     → FAILED: empty data or recipient

=== Успешные команды: 6 из 8 ===

Индивидуальные задания

Вариант 1. FTP-команды

Базовый класс: AbstractFTPCommand (защищённые: timestamp, status; чисто виртуальные: execute(), getName(), getDescription(); виртуальный деструктор). Производные: ConnectCommand (host, port; execute: [CONNECT] Подключение к <host>:<port> → OK), UploadCommand (filename, size; execute: [UPLOAD] <filename> (<size> байт) → OK/FAILED), DownloadCommand (filename; execute: [DOWNLOAD] <filename> → OK/FILE_NOT_FOUND), DeleteCommand (filename; execute: [DELETE] <filename> → OK/DENIED), ListCommand (path; execute: [LIST] <path> → файл1, файл2, ...), ChangeDirCommand (path; execute: [CD] <path> → OK/NOT_FOUND). Обработчик: FTPHandler — addCommand(), executeAll(), showHistory(), showSuccessful(), clearHistory().


Вариант 2. HTTP-команды

Базовый класс: AbstractHTTPCommand (защищённые: timestamp, status; чисто виртуальные: execute(), getName(), getDescription(); виртуальный деструктор). Производные: GetCommand (url; execute: [GET] <url> → 200 OK / 404 Not Found), PostCommand (url, body; execute: [POST] <url> (body: <size> байт) → 201 Created), PutCommand (url, body; execute: [PUT] <url> → 200 OK), DeleteCommand (url; execute: [DELETE] <url> → 204 No Content), HeadCommand (url; execute: [HEAD] <url> → 200 OK (headers only)), OptionsCommand (url; execute: [OPTIONS] <url> → Allow: GET, POST, PUT, DELETE). Обработчик: HTTPHandler — addCommand(), executeAll(), showHistory(), showSuccessful(), clearHistory().


Вариант 3. HTTP-команды

Базовый класс: AbstractHTTPCommand. Производные: GetCommand (url), PostCommand (url, body), PutCommand (url, body), DeleteCommand (url), HeadCommand (url), OptionsCommand (url). Обработчик: HTTPHandler.


Вариант 4. SMTP-команды

Базовый класс: AbstractMailCommand. Производные: HELOCommand (domain), MAILFROMCommand (email), RCPTTOCommand (email), DATACOMMAND (subject, body), QUITCommand, RSETCommand. Обработчик: SMTPHandler.


Вариант 5. DNS-команды

Базовый класс: AbstractDNSCommand. Производные: LookupCommand (domain, type), AddRecordCommand (domain, type, value), RemoveRecordCommand (domain), ListZoneCommand (zone), FlushCacheCommand, StatusCommand. Обработчик: DNSHandler.


Вариант 6. SSH-команды

Базовый класс: AbstractSSHCommand. Производные: ConnectCommand (host, user), ExecuteCommand (command), SCPUploadCommand (local, remote), SCPDownloadCommand (remote, local), TunnelCommand (localPort, remotePort), DisconnectCommand. Обработчик: SSHHandler.


Вариант 7. Команды управления IoT

Базовый класс: AbstractIoTCommand. Производные: ReadSensorCommand (deviceId, type), SetActuatorCommand (deviceId, value), RegisterDeviceCommand (id, type), RemoveDeviceCommand (id), ListDevicesCommand, GetStatusCommand (id). Обработчик: IoTHandler.


Вариант 8. Команды мониторинга

Базовый класс: AbstractMonitorCommand. Производные: CheckCPUCommand (host, threshold), CheckMemoryCommand (host, threshold), CheckDiskCommand (host, path), CheckServiceCommand (host, service), PingCommand (host), TopProcessesCommand (host, count). Обработчик: MonitorHandler.


Вариант 9. Команды управления контейнерами

Базовый класс: AbstractContainerCommand. Производные: StartCommand (name), StopCommand (name), RestartCommand (name), BuildCommand (name, image), RemoveCommand (name), ListCommand. Обработчик: ContainerHandler.


Вариант 10. Команды балансировщика

Базовый класс: AbstractLBCommand. Производные: AddBackendCommand (ip, port), RemoveBackendCommand (ip), SetAlgorithmCommand (algo), EnableBackendCommand (ip), DisableBackendCommand (ip), ShowStatusCommand. Обработчик: LBHandler.


Вариант 11. Команды фаервола

Базовый класс: AbstractFirewallCommand. Производные: AddRuleCommand (from, to, port, action), RemoveRuleCommand (id), ListRulesCommand, EnableRuleCommand (id), DisableRuleCommand (id), ShowStatsCommand. Обработчик: FirewallHandler.


Вариант 12. Команды базы данных

Базовый класс: AbstractDBCommand. Производные: SelectCommand (table, columns, where), InsertCommand (table, values), UpdateCommand (table, set, where), DeleteCommand (table, where), CreateTableCommand (table, columns), DropTableCommand (table). Обработчик: DBHandler.


Вариант 13. Команды чата

Базовый класс: AbstractChatCommand. Производные: JoinCommand (room, username), LeaveCommand (room), SendMessageCommand (room, text), PrivateMessageCommand (to, text), ListRoomsCommand, ListUsersCommand (room). Обработчик: ChatHandler.


Вариант 14. Команды VPN

Базовый класс: AbstractVPNCommand. Производные: ConnectCommand (server, protocol), DisconnectCommand, StatusCommand, ListServersCommand, SetDNSSommand (dns), CheckSpeedCommand (server). Обработчик: VPNHandler.


Вариант 15. Команды файлового сервера

Базовый класс: AbstractFileCommand. Производные: CreateFileCommand (path, size), DeleteFileCommand (path), MoveCommand (from, to), CopyCommand (from, to), SetPermissionsCommand (path, perms), GetInfoCommand (path). Обработчик: FileHandler.


Вариант 16. Команды аутентификации

Базовый класс: AbstractAuthCommand. Производные: RegisterCommand (login, password), LoginCommand (login, password), LogoutCommand, ChangePasswordCommand (old, new), ResetPasswordCommand (email), CheckTokenCommand (token). Обработчик: AuthHandler.


Вариант 17. Команды кэша

Базовый класс: AbstractCacheCommand. Производные: GetCommand (key), SetCommand (key, value, ttl), DeleteCommand (key), FlushCommand, StatsCommand, ExistsCommand (key). Обработчик: CacheHandler.


Вариант 18. Команды очереди сообщений

Базовый класс: AbstractQueueCommand. Производные: PublishCommand (topic, message), SubscribeCommand (topic), UnsubscribeCommand (topic), CreateTopicCommand (name), DeleteTopicCommand (name), ListTopicsCommand. Обработчик: QueueHandler.


Вариант 19. Команды резервного копирования

Базовый класс: AbstractBackupCommand. Производные: FullBackupCommand (source, destination), IncrementalCommand (source, destination), RestoreCommand (backup, target), ScheduleCommand (source, interval), ListBackupsCommand, VerifyCommand (backup). Обработчик: BackupHandler.


Вариант 20. Команды CI/CD

Базовый класс: AbstractCICommand. Производные: BuildCommand (project, branch), TestCommand (project, suite), DeployCommand (project, env), RollbackCommand (project, version), StatusCommand (project), ListProjectsCommand. Обработчик: CIHandler.


Порядок выполнения

  1. Создать проект C++ в Qt Creator (CMake).
  2. Определить абстрактный класс AbstractCommand.
  3. Реализовать все производные классы команд с переопределением execute(), getName(), getDescription().
  4. Реализовать класс CommandHandler с полиморфным выполнением.
  5. В main() создать команды, выполнить, вывести результаты.
  6. Скомпилировать, запустить, сохранить скриншоты.

Контрольные вопросы

  1. Что такое виртуальная функция и как она реализуется в C++ (vtable)?
  2. Что такое чисто виртуальная функция? Можно ли создать объект абстрактного класса?
  3. Что означает ключевое слово override? Чем отличается переопределение от перегрузки?
  4. Почему деструктор базового класса должен быть виртуальным? Что произойдёт, если он не виртуальный?
  5. Что такое статический и динамический полиморфизм? Приведите примеры.
  6. Можно ли вызвать чисто виртуальную функцию из конструктора базового класса?
  7. Какова роль указателя на базовый класс при работе с коллекцией объектов производных классов?
  8. В чём преимущество паттерна «Команда» для сетевых приложений?

Содержание отчёта

  1. Тема, цель и задание лабораторной работы.
  2. Диаграмма иерархии классов команд.
  3. Текст программы с комментариями.
  4. Скриншоты результата выполнения программы.
  5. Ответы на контрольные вопросы.
Наверх
Лаб. работа “Организация потоков, параллельной обработки, синхронизации и распределённой обработки синхронизуемых участков кода”
Лаб. работа “Средства языка для организации работы в сети. Основные классы и интерфейсы реализации сетевого взаимодействия”