kutuzzzov

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

Oct 20th, 2025 (edited)
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.12 KB | None | 0 0
  1. 🔹 Задача 1. **Базовая реализация полиморфизма**
  2.  
  3. **Условие**:  
  4. Создайте базовый класс `Figure` с виртуальной функцией `draw()`. Создайте два производных класса: `Circle` и `Square`, переопределяющих `draw()`. Продемонстрируйте вызов правильной версии функции через указатель на базовый класс.
  5.  
  6. #include <iostream>
  7. using namespace std;
  8.  
  9. // напишите решение ниже
  10.  
  11. int main() {
  12.     Circle c;
  13.     Square s;
  14.     Figure* f1 = &c;
  15.     Figure* f2 = &s;
  16.  
  17.     f1->draw(); // Рисую круг
  18.     f2->draw(); // Рисую квадрат
  19. }
  20.  
  21. > 💡 **Обучение**: Демонстрация базового полиморфизма через виртуальные функции.
  22.  
  23. ---
  24.  
  25. ## 🔹 Задача 2. **Чисто виртуальная функция и абстрактный класс**
  26.  
  27. **Условие**:  
  28. Создайте абстрактный класс `Animal` с чисто виртуальной функцией `makeSound()`. Реализуйте классы `Dog` и `Cat`, которые переопределяют эту функцию. Попытайтесь создать объект `Animal` — объясните ошибку.
  29.  
  30. #include <iostream>
  31. using namespace std;
  32.  
  33. // напишите решение ниже
  34.  
  35. int main() {
  36.     Dog d;
  37.     Cat c;
  38.     Animal* a1 = &d;
  39.     Animal* a2 = &c;
  40.  
  41.     a1->makeSound(); // Гав!
  42.     a2->makeSound(); // Мяу!
  43.  
  44.     // Animal a; // ❌ Ошибка: нельзя создать объект абстрактного класса
  45. }
  46.  
  47. > 💡 **Обучение**: Абстрактные классы задают интерфейс, но не могут создавать объекты.
  48.  
  49. ---
  50.  
  51. ## 🔹 Задача 3. **Виртуальный деструктор — демонстрация важности**
  52.  
  53. **Условие**:  
  54. Создайте базовый класс `Base` и производный `Derived`, оба с деструкторами, выводящими сообщение. Создайте объект `Derived`, удалите его через указатель на `Base`. Сначала без виртуального деструктора, затем с ним. Сравните результат.
  55.  
  56. #include <iostream>
  57. using namespace std;
  58.  
  59. // Без virtual
  60. // напишите решение ниже
  61.  
  62. // С virtual
  63. // напишите решение ниже
  64.  
  65. int main() {
  66.     cout << "Без virtual:\n";
  67.     Base1* p1 = new Derived1();
  68.     delete p1; // Вывод: ~Base1() — деструктор Derived НЕ вызван!
  69.  
  70.     cout << "\nС virtual:\n";
  71.     Base2* p2 = new Derived2();
  72.     delete p2; // Вывод: ~Derived2(), затем ~Base2()
  73. }
  74.  
  75. > 💡 **Обучение**: Без виртуального деструктора — утечка ресурсов и неопределённое поведение.
  76.  
  77. ---
  78.  
  79. ## 🔹 Задача 4. **Полиморфная коллекция объектов**
  80.  
  81. **Условие**:  
  82. Создайте вектор указателей на базовый класс `Shape` (с чисто виртуальной функцией `area()`). Добавьте в него объекты `Circle` и `Rectangle`. Выведите площадь каждой фигуры.
  83.  
  84. #include <iostream>
  85. #include <vector>
  86. #include <cmath>
  87. using namespace std;
  88.  
  89. // напишите решение ниже
  90.  
  91. int main() {
  92.     vector<Shape*> shapes;
  93.     shapes.push_back(new Circle(2.0));
  94.     shapes.push_back(new Rectangle(3.0, 4.0));
  95.  
  96.     for (const auto& shape : shapes) {
  97.         cout << "Площадь: " << shape->area() << endl;
  98.     }
  99.  
  100.     // Очистка памяти
  101.     for (auto* s : shapes) delete s;
  102. }
  103.  
  104. > 💡 **Обучение**: Работа с коллекцией полиморфных объектов.
  105.  
  106. ---
  107.  
  108. ## 🔹 Задача 5. **Использование `override` для защиты от ошибок**
  109.  
  110. **Условие**:  
  111. Создайте базовый класс `Vehicle` с виртуальной функцией `startEngine()`. В производном классе `Car` попытайтесь переопределить функцию с опечаткой (`startEngin`). Используйте `override` и покажите, как компилятор ловит ошибку.
  112.  
  113. // напишите решение ниже
  114.  
  115. > 💡 **Обучение**: `override` защищает от случайных ошибок при переопределении.
  116.  
  117. ---
  118.  
  119. ## 🔹 Задача 6. **Вызов виртуальной функции из конструктора/деструктора**
  120.  
  121. **Условие**:  
  122. Создайте базовый класс `Base` и производный `Derived`. В конструкторе `Base` вызовите виртуальную функцию `foo()`. Объясните, какая версия функции вызовется и почему.
  123.  
  124. #include <iostream>
  125. using namespace std;
  126.  
  127. // напишите решение ниже
  128.  
  129. int main() {
  130.     Derived d;
  131. }
  132.  
  133. **Вывод**:
  134. Base::foo()
  135. Derived::foo()
  136.  
  137. > 💡 **Обучение**: Во время выполнения конструктора базового класса объект **ещё не является** объектом производного класса → вызывается версия базового класса.
  138.  
  139. ---
  140.  
  141. ## 🔹 Задача 7. **Интерфейсный класс (все функции чисто виртуальные)**
  142.  
  143. **Условие**:  
  144. Создайте интерфейс `Drawable` с функцией `draw() = 0` и `Printable` с `print() = 0`. Создайте класс `Text`, реализующий оба интерфейса.
  145.  
  146. #include <iostream>
  147. using namespace std;
  148.  
  149. // напишите решение ниже
  150.  
  151. int main() {
  152.     Text t;
  153.     Drawable* d = &t;
  154.     Printable* p = &t;
  155.  
  156.     d->draw(); // Drawing text
  157.     p->print(); // Printing text
  158. }
  159.  
  160. > 💡 **Обучение**: Множественное наследование от интерфейсов — безопасно и полезно.
  161.  
  162. ---
  163.  
  164. ## 🔹 Задача 8. **Полиморфизм с использованием ссылок**
  165.  
  166. **Условие**:  
  167. Перепишите задачу 1, но используйте **ссылки** вместо указателей для демонстрации полиморфизма.
  168.  
  169. #include <iostream>
  170. using namespace std;
  171.  
  172. // напишите решение ниже
  173.  
  174. int main() {
  175.     Cow cow;
  176.     makeItSound(cow); // Moo!
  177. }
  178.  
  179. > 💡 **Обучение**: Полиморфизм работает и со ссылками, и с указателями.
  180.  
  181. ---
  182.  
  183. ## 🔹 Задача 9. **Виртуальные функции и наследование более чем одного уровня**
  184.  
  185. **Условие**:  
  186. Создайте иерархию: `Animal` → `Mammal` → `Dog`. Все имеют виртуальную функцию `speak()`. Покажите, что вызывается версия самого "глубокого" класса.
  187.  
  188. #include <iostream>
  189. using namespace std;
  190.  
  191. // напишите решение ниже
  192.  
  193. int main() {
  194.     Dog dog;
  195.     Animal* a = &dog;
  196.     a->speak(); // Woof!
  197. }
  198.  
  199. > 💡 **Обучение**: Виртуальность наследуется по всей цепочке.
  200.  
  201. ---
  202.  
  203. ## 🔹 Задача 10. **Полиморфизм с умными указателями**
  204.  
  205. **Условие**:  
  206. Перепишите задачу 4, используя `std::unique_ptr` вместо сырых указателей.
  207.  
  208. #include <iostream>
  209. #include <vector>
  210. #include <memory>
  211. #include <cmath>
  212. using namespace std;
  213.  
  214. // напишите решение ниже
  215.  
  216. int main() {
  217.     vector<unique_ptr<Shape>> shapes;
  218.     shapes.push_back(make_unique<Circle>(1.0));
  219.     shapes.push_back(make_unique<Square>(2.0));
  220.  
  221.     for (const auto& shape : shapes) {
  222.         cout << "Area: " << shape->area() << endl;
  223.     }
  224.     // Память освобождается автоматически
  225. }
  226.  
  227. ===========================================================
  228.  
  229.  
  230. ### **Задача 1: Управление транспортными средствами**
  231.  
  232. **Описание:** Создайте иерархию классов для различных видов транспорта (`Vehicle`, `Car`, `Bicycle`, `Airplane`). У каждого транспорта есть метод `move()`, который ведёт себя по-разному.
  233.  
  234. #include <iostream>
  235. #include <vector>
  236.  
  237. // ваше решение ниже
  238.  
  239. int main() {
  240.     std::vector<Vehicle*> fleet = {new Car, new Bicycle, new Airplane};
  241.  
  242.     for (auto v : fleet) {
  243.         v->move();
  244.     }
  245.  
  246.     for (auto v : fleet) {
  247.         delete v;
  248.     }
  249.     return 0;
  250. }
  251.  
  252. ---
  253.  
  254. ### **Задача 2: Обработка платежей**
  255.  
  256. **Описание:** Создайте систему обработки платежей (`Payment`, `CreditCard`, `PayPal`, `BankTransfer`), где каждый метод обработки отличается.
  257.  
  258. #include <iostream>
  259. #include <vector>
  260.  
  261. // ваше решение ниже
  262.  
  263. int main() {
  264.     std::vector<Payment*> payments = {new CreditCard, new PayPal, new BankTransfer};
  265.  
  266.     for (auto p : payments) {
  267.         p->process();
  268.     }
  269.  
  270.     for (auto p : payments) {
  271.         delete p;
  272.     }
  273.     return 0;
  274. }
  275.  
  276. ---
  277.  
  278. ### **Задача 3: Рисование фигур**
  279.  
  280. **Описание:** Используйте виртуальные функции для рисования различных геометрических фигур (`Shape`, `Circle`, `Rectangle`, `Triangle`), каждая из которых реализует метод `draw()` по-своему.
  281.  
  282. #include <iostream>
  283. #include <vector>
  284.  
  285. // ваше решение ниже
  286.  
  287. int main() {
  288.     std::vector<Shape*> shapes = {new Circle, new Rectangle, new Triangle};
  289.  
  290.     for (auto s : shapes) {
  291.         s->draw();
  292.     }
  293.  
  294.     for (auto s : shapes) {
  295.         delete s;
  296.     }
  297.     return 0;
  298. }
  299.  
  300. ---
  301.  
  302. ### **Задача 4: Животные и звуки**
  303.  
  304. **Описание:** Класс `Animal` с виртуальной функцией `makeSound()`, реализованной в подклассах (`Dog`, `Cat`, `Cow`).
  305.  
  306. #include <iostream>
  307. #include <vector>
  308.  
  309. // ваше решение ниже
  310.  
  311. int main() {
  312.     std::vector<Animal*> animals = {new Dog, new Cat, new Cow};
  313.  
  314.     for (auto a : animals) {
  315.         a->makeSound();
  316.     }
  317.  
  318.     for (auto a : animals) {
  319.         delete a;
  320.     }
  321.     return 0;
  322. }
  323.  
  324. ---
  325.  
  326. ### **Задача 5: Управление файлами**
  327.  
  328. **Описание:** Имитация обработки файлов разных типов (`File`, `TextFile`, `ImageFile`, `VideoFile`), где каждый тип файла имеет свой метод `open()`.
  329.  
  330. #include <iostream>
  331. #include <vector>
  332.  
  333. // ваше решение ниже
  334.  
  335. int main() {
  336.     std::vector<File*> files = {new TextFile, new ImageFile, new VideoFile};
  337.  
  338.     for (auto f : files) {
  339.         f->open();
  340.     }
  341.  
  342.     for (auto f : files) {
  343.         delete f;
  344.     }
  345.     return 0;
  346. }
  347.  
  348. ---
  349.  
  350. ### **Задача 6: Управление сотрудниками**
  351.  
  352. **Описание:** Различные типы сотрудников (`Employee`, `Manager`, `Engineer`, `Salesperson`) с разными методами `work()`.
  353.  
  354. #include <iostream>
  355. #include <vector>
  356.  
  357. // ваше решение ниже
  358.  
  359. int main() {
  360.     std::vector<Employee*> staff = {new Manager, new Engineer, new Salesperson};
  361.  
  362.     for (auto e : staff) {
  363.         e->work();
  364.     }
  365.  
  366.     for (auto e : staff) {
  367.         delete e;
  368.     }
  369.     return 0;
  370. }
  371.  
  372. ---
  373.  
  374. ### **Задача 7: Работа с фигурами (с вычислением площади)**
  375.  
  376. **Описание:** Используйте виртуальные функции для вычисления площади разных фигур (`Shape`, `Circle`, `Rectangle`).
  377.  
  378. #include <iostream>
  379. #include <vector>
  380.  
  381. // ваше решение ниже
  382.  
  383. int main() {
  384.     std::vector<Shape*> shapes = {new Circle(5), new Rectangle(4, 6)};
  385.  
  386.     for (auto s : shapes) {
  387.         std::cout << "Area: " << s->getArea() << "\n";
  388.     }
  389.  
  390.     for (auto s : shapes) {
  391.         delete s;
  392.     }
  393.     return 0;
  394. }
  395.  
  396. ---
  397.  
  398. ### **Задача 8: Игровые персонажи**
  399.  
  400. **Описание:** Игровые персонажи (`Character`, `Warrior`, `Mage`, `Archer`) с уникальным методом `attack()`.
  401.  
  402. #include <iostream>
  403. #include <vector>
  404.  
  405. // ваше решение ниже
  406.  
  407. int main() {
  408.     std::vector<Character*> party = {new Warrior, new Mage, new Archer};
  409.  
  410.     for (auto c : party) {
  411.         c->attack();
  412.     }
  413.  
  414.     for (auto c : party) {
  415.         delete c;
  416.     }
  417.     return 0;
  418. }
  419.  
  420. ---
  421.  
  422. ### **Задача 9: Печать документов**
  423.  
  424. **Описание:** Различные типы документов (`Document`, `PDF`, `Word`, `ImageDoc`) с разными способами печати.
  425.  
  426. #include <iostream>
  427. #include <vector>
  428.  
  429. // ваше решение ниже
  430.  
  431. int main() {
  432.     std::vector<Document*> docs = {new PDF, new Word, new ImageDoc};
  433.  
  434.     for (auto d : docs) {
  435.         d->print();
  436.     }
  437.  
  438.     for (auto d : docs) {
  439.         delete d;
  440.     }
  441.     return 0;
  442. }
  443. ```
  444.  
  445. ---
  446.  
  447. ### **Задача 10: Управление устройствами**
  448.  
  449. **Описание:** Устройства (`Device`, `Phone`, `Laptop`, `Tablet`) с методом `turnOn()`.
  450.  
  451. #include <iostream>
  452. #include <vector>
  453.  
  454. // ваше решение ниже
  455.  
  456. int main() {
  457.     std::vector<Device*> devices = {new Phone, new Laptop, new Tablet};
  458.  
  459.     for (auto d : devices) {
  460.         d->turnOn();
  461.     }
  462.  
  463.     for (auto d : devices) {
  464.         delete d;
  465.     }
  466.     return 0;
  467. }
Add Comment
Please, Sign In to add comment