shushus

Спринт 11. Наследование - детали.

Mar 26th, 2023
570
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.79 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. people.h
  3. -----------------------------------------------------------------------
  4. #pragma once
  5.  
  6. #include <string>
  7.  
  8. class Person;
  9.  
  10. class PersonObserver {
  11. public:
  12.     virtual void OnSatisfactionChanged(Person&, int, int) {}
  13.  
  14. protected:
  15.     ~PersonObserver() = default;
  16. };
  17.  
  18. class Person {
  19. public:
  20.     Person(const std::string& name, int age) : name_(name),
  21.                                                age_(age) {}
  22.     virtual ~Person() = default;
  23.  
  24.     const std::string& GetName() const {
  25.         return name_;
  26.     }
  27.    
  28.     int GetAge() const {
  29.         return age_;
  30.     }
  31.    
  32.     int GetSatisfaction() const {
  33.         return satisfaction_;
  34.     }
  35.    
  36.     auto GetObserver() const {
  37.         return observer_;
  38.     }
  39.  
  40.     void SetObserver(PersonObserver* observer) {
  41.         observer_ = observer;
  42.     }
  43.  
  44.     virtual void Dance() {
  45.         ++dance_count_;
  46.         SetSatisfaction(satisfaction_ + 1);
  47.     }
  48.  
  49.     int GetDanceCount() const {
  50.         return dance_count_;
  51.     }
  52.  
  53.     virtual void LiveADay() {}
  54.  
  55. protected:
  56.    
  57.     virtual void SetSatisfaction(int value) {
  58.         if (satisfaction_ != value) {
  59.             int old_value = satisfaction_;
  60.             satisfaction_ = value;
  61.             if (observer_) {
  62.                 observer_->OnSatisfactionChanged(*this, old_value, satisfaction_);
  63.             }
  64.         }
  65.     }
  66.  
  67. private:
  68.     std::string name_;
  69.     int age_;
  70.     int satisfaction_ = 100;
  71.     PersonObserver* observer_ = nullptr;
  72.     int dance_count_ = 0;
  73. };
  74.  
  75. class Worker : public Person {
  76. public:
  77.     Worker(const std::string& name, int age) : Person(name, age) {}
  78.  
  79.     void Dance() override {
  80.         Person::Dance();
  81.        
  82.         if (int age = GetAge(); age > 30 && age < 40) {
  83.             SetSatisfaction(GetSatisfaction() + 1);
  84.         }
  85.     }
  86.  
  87.     void Work() {
  88.         ++work_;
  89.         SetSatisfaction(GetSatisfaction() - 5);
  90.     }
  91.  
  92.     int GetWorkDone() const {
  93.         return work_;
  94.     }
  95.  
  96.     void LiveADay() override {
  97.         Work();
  98.     }
  99.    
  100. private:
  101.     int work_ = 0;
  102. };
  103.  
  104. class Student : public Person {
  105. public:
  106.     Student(const std::string& name, int age) : Person(name, age) {}
  107.  
  108.     void Study() {
  109.         ++study_;
  110.         SetSatisfaction(GetSatisfaction() - 3);
  111.     }
  112.  
  113.     void Dance() override {
  114.         auto old_value = GetSatisfaction();
  115.         Person::Dance();
  116.        
  117.         if (GetObserver()) {
  118.             GetObserver()->OnSatisfactionChanged(*this, old_value, GetSatisfaction());
  119.         }
  120.     }
  121.  
  122.     int GetKnowledgeLevel() const {
  123.         return study_;
  124.     }
  125.  
  126.     void LiveADay() override {
  127.         Study();
  128.     }
  129.    
  130. private:
  131.     int study_ = 0;
  132. };
  133. -----------------------------------------------------------------------
  134. supervisor.h
  135. -----------------------------------------------------------------------
  136. #pragma once
  137.  
  138. #include "people.h"
  139.  
  140. class SatisfactionSupervisor : public PersonObserver {
  141. public:
  142.     SatisfactionSupervisor(int min_satisfaction, int max_satisfaction) : min_(min_satisfaction),
  143.                                                                          max_(max_satisfaction) {}
  144.  
  145.     void OnSatisfactionChanged(Person& person, int old_value, int new_value) {
  146.        
  147.         if (new_value < min_ && (new_value - old_value) < 0) {
  148.            
  149.             while (person.GetSatisfaction() < max_) {
  150.                 person.Dance();
  151.             }
  152.         }
  153.     }
  154.    
  155. private:
  156.     int min_ = 0;
  157.     int max_ = 0;
  158. };
  159. -----------------------------------------------------------------------
  160. simulation.cpp
  161. -----------------------------------------------------------------------
  162. #include "people.h"
  163. #include "supervisor.h"
  164.  
  165. #include <cassert>
  166. #include <iostream>
  167. #include <memory>
  168. #include <optional>
  169. #include <vector>
  170.  
  171. using namespace std;
  172.  
  173. void RunSimulation(vector<unique_ptr<Person>>& people, int num_days) {
  174.     for (int i = 0; i < num_days; ++i) {
  175.         for (auto& person : people) {
  176.             person->LiveADay();
  177.         }
  178.     }
  179. }
  180.  
  181. void Tests() {
  182.     struct TestObserver : public PersonObserver {
  183.         Person* person = nullptr;
  184.         optional<int> old_satisfaction;
  185.         optional<int> new_satisfaction;
  186.         void OnSatisfactionChanged(Person& p, int old_value, int new_value) override {
  187.             this->person = &p;
  188.             this->old_satisfaction = old_value;
  189.             this->new_satisfaction = new_value;
  190.         }
  191.     };
  192.  
  193.     {
  194.         Person p{"Ivan"s, 30};
  195.         assert(p.GetDanceCount() == 0);
  196.         const int old_satisfaction = p.GetSatisfaction();
  197.         assert(old_satisfaction == 100);
  198.         p.Dance();
  199.         assert(p.GetDanceCount() == 1);
  200.         assert(p.GetSatisfaction() == old_satisfaction + 1);
  201.  
  202.         TestObserver o;
  203.         p.SetObserver(&o);
  204.         assert(o.person == nullptr);
  205.  
  206.         p.Dance();
  207.         assert(o.person == &p);
  208.         assert(o.old_satisfaction == old_satisfaction + 1);
  209.         assert(o.new_satisfaction == old_satisfaction + 2);
  210.     }
  211.  
  212.     {
  213.         Worker w{"Ivan"s, 35};
  214.         const int old_satisfaction = w.GetSatisfaction();
  215.         assert(w.GetWorkDone() == 0);
  216.         w.Work();
  217.         assert(w.GetSatisfaction() == old_satisfaction - 5);
  218.         assert(w.GetWorkDone() == 1);
  219.  
  220.         w.LiveADay();
  221.         assert(w.GetSatisfaction() == old_satisfaction - 10);
  222.         assert(w.GetWorkDone() == 2);
  223.  
  224.         assert(w.GetDanceCount() == 0);
  225.         w.Dance();
  226.         assert(w.GetDanceCount() == 1);
  227.         assert(w.GetSatisfaction() == old_satisfaction - 10 + 2);
  228.     }
  229.  
  230.     {
  231.         Student s{"Ivan"s, 18};
  232.         const int old_satisfaction = s.GetSatisfaction();
  233.         assert(s.GetKnowledgeLevel() == 0);
  234.         s.Study();
  235.         assert(s.GetSatisfaction() == old_satisfaction - 3);
  236.         assert(s.GetKnowledgeLevel() == 1);
  237.  
  238.         s.LiveADay();
  239.         assert(s.GetSatisfaction() == old_satisfaction - 6);
  240.         assert(s.GetKnowledgeLevel() == 2);
  241.  
  242.         assert(s.GetDanceCount() == 0);
  243.         s.Dance();
  244.         assert(s.GetDanceCount() == 1);
  245.         assert(s.GetSatisfaction() == old_satisfaction - 6 + 1);
  246.     }
  247.  
  248.     {
  249.         Worker w("Ivan"s, 35);
  250.  
  251.         SatisfactionSupervisor sup{95, 97};
  252.         w.SetObserver(&sup);
  253.  
  254.         w.Work();
  255.         assert(w.GetSatisfaction() == 95);
  256.  
  257.         assert(w.GetDanceCount() == 0);
  258.  
  259.         w.Work();
  260.  
  261.         assert(w.GetDanceCount() == 4);
  262.         assert(w.GetSatisfaction() == 98);
  263.     }
  264.  
  265.     {
  266.         struct DestructivePerson : public Person {
  267.             explicit DestructivePerson(bool& destruction_flag)
  268.                 : Person("test"s, 20)
  269.                 , destruction_flag_(destruction_flag) {
  270.                 destruction_flag_ = false;
  271.             }
  272.  
  273.             ~DestructivePerson() {
  274.                 destruction_flag_ = true;
  275.             }
  276.  
  277.             bool& destruction_flag_;
  278.         };
  279.  
  280.         bool person_destroyed = false;
  281.         unique_ptr<Person> p = make_unique<DestructivePerson>(person_destroyed);
  282.         assert(!person_destroyed);
  283.         p.reset();
  284.         assert(person_destroyed);
  285.     }
  286. }
  287.  
  288. int main() {
  289.     Tests();
  290.  
  291.     vector<unique_ptr<Person>> people;
  292.     people.emplace_back(make_unique<Worker>("Mario"s, 35));
  293.     people.emplace_back(make_unique<Student>("Harry Potter"s, 18));
  294.  
  295.     SatisfactionSupervisor supervisor(90, 100);
  296.     for (auto& person : people) {
  297.         person->SetObserver(&supervisor);
  298.     }
  299.  
  300.     RunSimulation(people, 10);
  301.  
  302.     for (auto& person : people) {
  303.         cout << person->GetName() << "' satisfaction: "s << person->GetSatisfaction() << ", dance count: "s
  304.              << person->GetDanceCount() << endl;
  305.     }
  306.  
  307.     for (auto& person : people) {
  308.         person->SetObserver(nullptr);
  309.     }
  310. }
Advertisement
Add Comment
Please, Sign In to add comment