Итоги — Иерархия сотрудников
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 55 из 104.
Задание
ЛегкоДавайте создадим полноценную систему иерархии сотрудников, которая объединит все концепции наследования, изученные вами в этой главе. Вы создадите структуру компании с различными типами сотрудников, которые имеют общие атрибуты, но обладают специализированным поведением.
Вы организуете свой код в четырех файлах:
Employee.h: Определите базовый классEmployee, от которого будут наследоваться все типы сотрудников. У каждого сотрудника есть имя, ID и базовая зарплата. Включите:- Защищенные (protected) члены для имени (
std::string), id (int) и baseSalary (double) - Конструктор, который инициализирует все три значения
- Виртуальный метод
displayInfo(), который выводит:Employee: <name> (ID: <id>) - Виртуальный метод
calculateSalary(), который возвращает базовую зарплату - Виртуальный деструктор
- Защищенные (protected) члены для имени (
Manager.h: Определите классManager, который публично наследуется отEmployee. Менеджеры получают бонус в зависимости от размера их команды:- Закрытый (private) член
int teamSize - Конструктор, принимающий имя, id, базовую зарплату и размер команды — соответствующим образом вызовите конструктор базового класса
- Переопределите
displayInfo()для вывода:Manager: <name> (ID: <id>) - Team of <teamSize> - Переопределите
calculateSalary(), чтобы он возвращал базовую зарплату плюс 500 за каждого члена команды
- Закрытый (private) член
Developer.h: Определите классDeveloper, который публично наследуется отEmployee. У разработчиков есть основной язык программирования, и они получают бонус за навыки:- Закрытый (private) член
std::string language - Конструктор, принимающий имя, id, базовую зарплату и язык программирования
- Переопределите
displayInfo()для вывода:Developer: <name> (ID: <id>) - <language> - Переопределите
calculateSalary(), чтобы он возвращал базовую зарплату плюс бонус за навыки в размере 1000
- Закрытый (private) член
main.cpp: Считайте шесть входных значений (каждое на отдельной строке):- Имя менеджера
- ID менеджера
- Базовая зарплата менеджера
- Имя разработчика
- ID разработчика
- Базовая зарплата разработчика
Создайте объект Manager с размером команды 4 и объект Developer, который специализируется на "C++". Сохраните указатели на оба объекта в массиве указателей
Employee*. Пройдите циклом по массиву, чтобы вызватьdisplayInfo()и вывести рассчитанную зарплату для каждого сотрудника в следующем формате:<displayInfo output> Salary: <displayInfo output> Salary: $<calculated salary>lt;calculated salary>Выведите пустую строку между сотрудниками. После отображения всех сотрудников правильно удалите динамически выделенные объекты.
Например, при входных данных Sarah, 101, 5000, Mike, 102 и 4500:
Manager: Sarah (ID: 101) - Team of 4
Salary: $7000
Developer: Mike (ID: 102) - C++
Salary: $5500Эта задача демонстрирует полиморфизм в действии — вызов виртуальных методов через указатели базового класса активирует правильные реализации производных классов. Не забудьте использовать ключевое слово override и включить виртуальный деструктор в базовый класс для корректной очистки памяти.
Попробуйте сами
#include <iostream>
#include <string>
#include "Employee.h"
#include "Manager.h"
#include "Developer.h"
using namespace std;
int main() {
// Считать входные данные для Manager
string managerName;
int managerId;
double managerSalary;
getline(cin, managerName);
cin >> managerId;
cin >> managerSalary;
cin.ignore();
// Считать входные данные для Developer
string developerName;
int developerId;
double developerSalary;
getline(cin, developerName);
cin >> developerId;
cin >> developerSalary;
// TODO: Создать объект Manager с размером команды 4
// TODO: Создать объект Developer, который специализируется на "C++"
// TODO: Создать массив указателей Employee* для хранения обоих сотрудников
// TODO: Пройти циклом по массиву и для каждого сотрудника:
// - Вызвать displayInfo()
// - Вывести: Salary: $<calculated salary>
// - Вывести пустую строку между сотрудниками (но не после последнего)
// TODO: Удалить динамически выделенные объекты
return 0;
}
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнер