Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit7546f0d0da487e16f0a8671c09a46e1cee2bc03a (patch)
Author
 Syndamia <kamen@syndamia.com>
2026-05-02 14:57:36 +0300
Committer
 Syndamia <kamen@syndamia.com>
2026-05-02 14:57:36 +0300
Files6462868cebe114a87ca38252af9a49bce6603286
oop-2025-solutions-7546f0d0da487e16f0a8671c09a46e1cee2bc03a.tar
oop-2025-solutions-7546f0d0da487e16f0a8671c09a46e1cee2bc03a.tar.gz
oop-2025-solutions-7546f0d0da487e16f0a8671c09a46e1cee2bc03a.zip
Parentc98c633b7087e3c52f4b05236f3509a9ec5f2bba (diff)
feat(Week10): Add solutions
diff --git a/Week10/Exercise01/Student.cpp b/Week10/Exercise01/Student.cpp
new file mode 100644
index 0000000..6c8d2ba
--- /dev/null
+++ b/Week10/Exercise01/Student.cpp
@@ -0,0 +1,5 @@
+#include "Student.h"
+
+void Student::Graduate() {
+ graduated = true;
+}
diff --git a/Week10/Exercise01/Student.h b/Week10/Exercise01/Student.h
new file mode 100644
index 0000000..65b1872
--- /dev/null
+++ b/Week10/Exercise01/Student.h
@@ -0,0 +1,14 @@
+#ifndef _STUDENT
+#define _STUDENT
+
+#include "User.h"
+
+class Student : public User {
+ bool graduated;
+ unsigned yearEnrolled;
+
+public:
+ void Graduate();
+};
+
+#endif /* _STUDENT */
diff --git a/Week10/Exercise01/Teacher.cpp b/Week10/Exercise01/Teacher.cpp
new file mode 100644
index 0000000..7cf9029
--- /dev/null
+++ b/Week10/Exercise01/Teacher.cpp
@@ -0,0 +1,5 @@
+#include "Teacher.h"
+
+void Teacher::ChangeStudents(unsigned teachingStudentsCount) {
+ this->teachingStudentsCount = teachingStudentsCount;
+}
diff --git a/Week10/Exercise01/Teacher.h b/Week10/Exercise01/Teacher.h
new file mode 100644
index 0000000..216d40e
--- /dev/null
+++ b/Week10/Exercise01/Teacher.h
@@ -0,0 +1,14 @@
+#ifndef _TEACHER
+#define _TEACHER
+
+#include "User.h"
+
+class Teacher : public User {
+ char subject[1024];
+ unsigned teachingStudentsCount;
+
+public:
+ void ChangeStudents(unsigned teachingStudentsCount);
+};
+
+#endif /* _TEACHER */
diff --git a/Week10/Exercise01/User.cpp b/Week10/Exercise01/User.cpp
new file mode 100644
index 0000000..fce9956
--- /dev/null
+++ b/Week10/Exercise01/User.cpp
@@ -0,0 +1,6 @@
+#include "User.h"
+#include <cstring>
+
+bool User::LogIn(const char* name, const char* password) {
+ return strcmp(this->name, name) == 0 && strcmp(this->password, password) == 0;
+}
diff --git a/Week10/Exercise01/User.h b/Week10/Exercise01/User.h
new file mode 100644
index 0000000..e0afcdc
--- /dev/null
+++ b/Week10/Exercise01/User.h
@@ -0,0 +1,14 @@
+#ifndef _USER
+#define _USER
+
+class User {
+ unsigned ID;
+ char name[1024];
+ char password[128];
+ unsigned yearRegistered;
+
+public:
+ bool LogIn(const char* name, const char* password);
+};
+
+#endif /* _USER */
diff --git a/Week10/Exercise02/CombustionVehicle.cpp b/Week10/Exercise02/CombustionVehicle.cpp
new file mode 100644
index 0000000..b431161
--- /dev/null
+++ b/Week10/Exercise02/CombustionVehicle.cpp
@@ -0,0 +1,69 @@
+#include "CombustionVehicle.h"
+
+CombustionVehicle::CombustionVehicle() : Vehicle(), cyllindersCount(), engineVolume() {
+ type = 2;
+}
+
+unsigned CombustionVehicle::GetCyllindersCount() const {
+ return cyllindersCount;
+}
+
+void CombustionVehicle::SetCyllindersCount(unsigned cyllindersCount) {
+ this->cyllindersCount = cyllindersCount;
+}
+
+double CombustionVehicle::GetEngineVolume() const {
+ return engineVolume;
+}
+
+void CombustionVehicle::SetEngineVolume(double engineVolume) {
+ this->engineVolume = engineVolume;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const CombustionVehicle& vehicle) {
+ ostr << (const Vehicle&)vehicle
+ << "Cyllinders count: " << vehicle.cyllindersCount << std::endl
+ << "Engine volume: " << vehicle.engineVolume << std::endl;
+ return ostr;
+}
+
+std::istream& operator>>(std::istream& istr, CombustionVehicle& vehicle) {
+ istr >> (Vehicle&)vehicle
+ >> vehicle.cyllindersCount
+ >> vehicle.engineVolume;
+ return istr;
+}
+
+bool CombustionVehicle::IsCombustionVehicle(const Vehicle& vehicle) {
+ // Как работят конвертиранията: в C++ има няколко конвертирания, те са главно
+ // const_cast, static_cast и reinterpret_cast.
+ // Стандартното конвертиране със скоби "(Type)(x)", се нарича експлицитно
+ // конвертиране и идва от C. Под C++, то просто пробва всички възможни
+ // конвертирания, докато някое е валидно (дори и като резултат да е грешно).
+ //
+ // const_cast конветира между това дали тип е константен или не.
+ // static_cast променя как поглеждаме посочената памет. С други думи,
+ // "тези битове/байтове тук вече трябва да се зачитат за този тип".
+ // reinterpret_cast прави по-сложна промяна, която цели да върне такива
+ // данни, че всичко да работи коректно. На теория, може и примерно да се
+ // задели нова памет в която да се пренесат данните които са ни предоставени.
+ //
+ // В нашия случай, CombustionVehicle има повече член-данни от vehicle, което
+ // означава че ако използваме static_cast (което експлицитното конвертиране
+ // ще избере), ще направим грешка.
+ // Един Vehicle обект заема ~1042 байта, докато CombustionVehicle заема ~1054.
+ // Това означава, че със static_cast ще зачитаме памет от 1042 байта като
+ // такава от 1054 и можем да пишем/четем извън предопределените адреси памет.
+ //
+ // В нашия случай това няма да се случи, но коректното решение е да
+ // използваме reinterpret_cast, който ще осигури че всичко от върнатата
+ // стойност може да се достъпи, без проблеми.
+ //
+ //
+ // А защо ни трябва конвертиране, нали CombustionVehicle е наследник,
+ // не можем ли директно от vehicle да вземем type?
+ // Еми, не можем, защото член-функция може да достъпва само член-данни и член-функции
+ // на обекти от същия тип. Т.е. няма никакъв специален достъп към Vehicle обекти,
+ // само всичко публично е налично, но има пълен достъп към CombustionVehicle обекти.
+ return reinterpret_cast<const CombustionVehicle&>(vehicle).type == 2;
+}
diff --git a/Week10/Exercise02/CombustionVehicle.h b/Week10/Exercise02/CombustionVehicle.h
new file mode 100644
index 0000000..7c102be
--- /dev/null
+++ b/Week10/Exercise02/CombustionVehicle.h
@@ -0,0 +1,27 @@
+#ifndef _COMBUSTIONVEHICLE
+#define _COMBUSTIONVEHICLE
+
+#include "Vehicle.h"
+#include <istream>
+#include <ostream>
+
+class CombustionVehicle : public Vehicle {
+ unsigned cyllindersCount;
+ double engineVolume;
+
+public:
+ CombustionVehicle();
+
+ unsigned GetCyllindersCount() const;
+ void SetCyllindersCount(unsigned cyllindersCount);
+
+ double GetEngineVolume() const;
+ void SetEngineVolume(double engineVolume);
+
+ friend std::ostream& operator<<(std::ostream& ostr, const CombustionVehicle& vehicle);
+ friend std::istream& operator>>(std::istream& istr, CombustionVehicle& vehicle);
+
+ static bool IsCombustionVehicle(const Vehicle& vehicle);
+};
+
+#endif /* _COMBUSTIONVEHICLE */
diff --git a/Week10/Exercise02/ElectricVehicle.cpp b/Week10/Exercise02/ElectricVehicle.cpp
new file mode 100644
index 0000000..deb3179
--- /dev/null
+++ b/Week10/Exercise02/ElectricVehicle.cpp
@@ -0,0 +1,79 @@
+#include "ElectricVehicle.h"
+
+ElectricVehicle::ElectricVehicle() : Vehicle(), batteryCapacity(), range(), chargingCapacity() {
+ type = 1;
+}
+
+double ElectricVehicle::GetBatteryCapacity() const {
+ return batteryCapacity;
+}
+
+void ElectricVehicle::SetBatteryCapacity(double batteryCapacity) {
+ this->batteryCapacity = batteryCapacity;
+}
+
+double ElectricVehicle::GetRange() const {
+ return range;
+}
+
+void ElectricVehicle::SetRange(double range) {
+ this->range = range;
+}
+
+double ElectricVehicle::GetCharingCapacity() const {
+ return chargingCapacity;
+}
+
+void ElectricVehicle::SetChargingCapacity(double chargingCapacity) {
+ this->chargingCapacity = chargingCapacity;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const ElectricVehicle& vehicle) {
+ ostr << (const Vehicle&)vehicle
+ << "Battery capacity: " << vehicle.batteryCapacity << std::endl
+ << "Range: " << vehicle.range << std::endl
+ << "Charging capacity: " << vehicle.chargingCapacity << std::endl;
+ return ostr;
+}
+
+std::istream& operator>>(std::istream& istr, ElectricVehicle& vehicle) {
+ istr >> (Vehicle&)vehicle
+ >> vehicle.batteryCapacity
+ >> vehicle.range
+ >> vehicle.chargingCapacity;
+ return istr;
+}
+
+bool ElectricVehicle::IsElectricVehicle(const Vehicle& vehicle) {
+ // Как работят конвертиранията: в C++ има няколко конвертирания, те са главно
+ // const_cast, static_cast и reinterpret_cast.
+ // Стандартното конвертиране със скоби "(Type)(x)", се нарича експлицитно
+ // конвертиране и идва от C. Под C++, то просто пробва всички възможни
+ // конвертирания, докато някое е валидно (дори и като резултат да е грешно).
+ //
+ // const_cast конветира между това дали тип е константен или не.
+ // static_cast променя как поглеждаме посочената памет. С други думи,
+ // "тези битове/байтове тук вече трябва да се зачитат за този тип".
+ // reinterpret_cast прави по-сложна промяна, която цели да върне такива
+ // данни, че всичко да работи коректно. На теория, може и примерно да се
+ // задели нова памет в която да се пренесат данните които са ни предоставени.
+ //
+ // В нашия случай, ElectricVehicle има повече член-данни от vehicle, което
+ // означава че ако използваме static_cast (което експлицитното конвертиране
+ // ще избере), ще направим грешка.
+ // Един Vehicle обект заема ~1042 байта, докато ElectricVehicle заема ~1054.
+ // Това означава, че със static_cast ще зачитаме памет от 1042 байта като
+ // такава от 1054 и можем да пишем/четем извън предопределените адреси памет.
+ //
+ // В нашия случай това няма да се случи, но коректното решение е да
+ // използваме reinterpret_cast, който ще осигури че всичко от върнатата
+ // стойност може да се достъпи, без проблеми.
+ //
+ //
+ // А защо ни трябва конвертиране, нали ElectricVehicle е наследник,
+ // не можем ли директно от vehicle да вземем type?
+ // Еми, не можем, защото член-функция може да достъпва само член-данни и член-функции
+ // на обекти от същия тип. Т.е. няма никакъв специален достъп към Vehicle обекти,
+ // само всичко публично е налично, но има пълен достъп към ElectricVehicle обекти.
+ return reinterpret_cast<const ElectricVehicle&>(vehicle).type == 1;
+}
diff --git a/Week10/Exercise02/ElectricVehicle.h b/Week10/Exercise02/ElectricVehicle.h
new file mode 100644
index 0000000..5a48b27
--- /dev/null
+++ b/Week10/Exercise02/ElectricVehicle.h
@@ -0,0 +1,31 @@
+#ifndef _ELECTRICVEHICLE
+#define _ELECTRICVEHICLE
+
+#include "Vehicle.h"
+#include <istream>
+#include <ostream>
+
+class ElectricVehicle : public Vehicle {
+ double batteryCapacity;
+ double range;
+ double chargingCapacity;
+
+public:
+ ElectricVehicle();
+
+ double GetBatteryCapacity() const;
+ void SetBatteryCapacity(double batteryCapacity);
+
+ double GetRange() const;
+ void SetRange(double range);
+
+ double GetCharingCapacity() const;
+ void SetChargingCapacity(double chargingCapacity);
+
+ friend std::ostream& operator<<(std::ostream& ostr, const ElectricVehicle& vehicle);
+ friend std::istream& operator>>(std::istream& istr, ElectricVehicle& vehicle);
+
+ static bool IsElectricVehicle(const Vehicle& vehicle);
+};
+
+#endif /* _ELECTRICVEHICLE */
diff --git a/Week10/Exercise02/Vehicle.cpp b/Week10/Exercise02/Vehicle.cpp
new file mode 100644
index 0000000..bbc6bf0
--- /dev/null
+++ b/Week10/Exercise02/Vehicle.cpp
@@ -0,0 +1,74 @@
+#include "Vehicle.h"
+#include <cstring>
+
+Vehicle::Vehicle() : model(), yearOfManufacture(), mileage(), ecoCategory(), weight(), horsePower() {
+ type = 0;
+}
+
+const char* Vehicle::GetModel() const {
+ return model;
+}
+
+void Vehicle::SetModel(char model[MODEL_LENGTH]) {
+ strcpy(this->model, model);
+}
+
+unsigned Vehicle::GetYearOfManufacture() const {
+ return yearOfManufacture;
+}
+
+void Vehicle::SetYearOfManufacture(unsigned yearOfManufacture) {
+ this->yearOfManufacture = yearOfManufacture;
+}
+
+double Vehicle::GetMileage() const {
+return mileage;
+}
+
+void Vehicle::SetMileage(double mileage) {
+ this->mileage = mileage;
+}
+
+unsigned short Vehicle::GetEcoCategory() const {
+ return ecoCategory;
+}
+
+void Vehicle::SetEcoCategory(unsigned short ecoCategory) {
+ this->ecoCategory = ecoCategory;
+}
+
+double Vehicle::GetWeight() const {
+ return weight;
+}
+
+void Vehicle::SetWeight(double weight) {
+ this->weight = weight;
+}
+
+double Vehicle::GetHorsePower() const {
+ return horsePower;
+}
+
+void Vehicle::SetHorsePower(double horsePower) {
+ this->horsePower = horsePower;
+}
+
+std::ostream& operator<<(std::ostream& ostr, const Vehicle& vehicle) {
+ ostr << vehicle.model << std::endl
+ << "Manufactured: " << vehicle.yearOfManufacture << std::endl
+ << "Mileage: " << vehicle.mileage << std::endl
+ << "Eco category: " << vehicle.ecoCategory << std::endl
+ << "Weight: " << vehicle.weight << std::endl
+ << "Horse power: " << vehicle.horsePower << std::endl;
+ return ostr;
+}
+
+std::istream& operator>>(std::istream& istr, Vehicle& vehicle) {
+ istr.getline(vehicle.model, MODEL_LENGTH);
+ istr >> vehicle.yearOfManufacture
+ >> vehicle.mileage
+ >> vehicle.ecoCategory
+ >> vehicle.weight
+ >> vehicle.horsePower;
+ return istr;
+}
diff --git a/Week10/Exercise02/Vehicle.h b/Week10/Exercise02/Vehicle.h
new file mode 100644
index 0000000..206e1b5
--- /dev/null
+++ b/Week10/Exercise02/Vehicle.h
@@ -0,0 +1,66 @@
+#ifndef _VEHICLE
+#define _VEHICLE
+
+#include <istream>
+#include <ostream>
+
+const unsigned MODEL_LENGTH = 1024;
+
+class Vehicle {
+ char model[MODEL_LENGTH];
+ unsigned yearOfManufacture;
+ double mileage;
+ unsigned short ecoCategory;
+ double weight;
+ double horsePower;
+
+
+public:
+ Vehicle();
+
+ const char* GetModel() const;
+ void SetModel(char model[MODEL_LENGTH]);
+
+ unsigned GetYearOfManufacture() const;
+ void SetYearOfManufacture(unsigned yearOfManufacture);
+
+ double GetMileage() const;
+ void SetMileage(double mileage);
+
+ unsigned short GetEcoCategory() const;
+ void SetEcoCategory(unsigned short ecoCategory);
+
+ double GetWeight() const;
+ void SetWeight(double weight);
+
+ double GetHorsePower() const;
+ void SetHorsePower(double horsePower);
+
+ // Имаме всички нужни селектори и мутатори, за да не се нуждаем
+ // от това операторите да са friend. Но въпреки това ще го
+ // имплементираме така.
+
+ friend std::ostream& operator<<(std::ostream& ostr, const Vehicle& vehicle);
+ friend std::istream& operator>>(std::istream& istr, Vehicle& vehicle);
+
+ // След като създадем динамично-заделен обект от
+ // клас наследник, можем да конвертираме указателя към
+ // базовия клас (т.е. CombustionVehicle* да стане Vehicle*).
+ // В този случай, ще имаме налични само нещата, които са
+ // достъпни във Vehicle, включително деструктора.
+ //
+ // Но CombustionVehicle има още член-данни, как ще разберем,
+ // че Vehicle* е всъщност CombustionVehicle*?
+ // Коректното решение, като стигнем до там, е да използваме
+ // виртуални деструктури.
+ //
+ // Текущото решение, което можем да направим, е да запазваме
+ // някаква допълнителна стойност, която е различна спрямо
+ // конкретния клас (наследник). След това ще правим проверки по
+ // нея, дали съответства на тази на даден клас, и ако да, конвертираме.
+protected:
+ unsigned type;
+};
+
+
+#endif /* _VEHICLE */
diff --git a/Week10/Exercise02/main.cpp b/Week10/Exercise02/main.cpp
new file mode 100644
index 0000000..980b9b2
--- /dev/null
+++ b/Week10/Exercise02/main.cpp
@@ -0,0 +1,57 @@
+#include "Vehicle.h"
+#include "CombustionVehicle.h"
+#include "ElectricVehicle.h"
+#include <iostream>
+
+int main() {
+ unsigned N;
+ std::cin >> N;
+
+ Vehicle** vehicles = new Vehicle*[N];
+ for (unsigned i = 0; i < N; ++i) {
+ char type;
+ std::cin >> type;
+ std::cin.ignore();
+
+ if (type == 'c') {
+ CombustionVehicle* vehicle = new CombustionVehicle;
+ std::cin >> *vehicle;
+ vehicles[i] = vehicle;
+ }
+ else if (type == 'e') {
+ ElectricVehicle* vehicle = new ElectricVehicle;
+ std::cin >> *vehicle;
+ vehicles[i] = vehicle;
+ }
+ else {
+ vehicles[i] = nullptr;
+ }
+ }
+
+ for (unsigned i = 0; i < N; ++i) {
+ if (vehicles[i] != nullptr)
+ std::cout << *vehicles[i];
+ }
+
+ for (unsigned i = 0; i < N; ++i) {
+ if (vehicles[i] == nullptr) {
+ continue;
+ }
+ // Това го правим, защото delete само вижда че обекта е "Vehicle",
+ // не вижда допълнителната памет, която се заделя за допълнителните
+ // член-данни, които запазваме при Combustion и Electric.
+
+ else if (CombustionVehicle::IsCombustionVehicle(*vehicles[i])) {
+ delete (CombustionVehicle*)vehicles[i];
+ }
+ else if (ElectricVehicle::IsElectricVehicle(*vehicles[i])) {
+ delete (ElectricVehicle*)vehicles[i];
+ }
+ else {
+ delete vehicles[i];
+ }
+ }
+ delete[] vehicles;
+
+ return 0;
+}
diff --git a/Week10/Exercise03/Date.h b/Week10/Exercise03/Date.h
new file mode 100644
index 0000000..716efef
--- /dev/null
+++ b/Week10/Exercise03/Date.h
@@ -0,0 +1,10 @@
+#ifndef _DATE
+#define _DATE
+
+struct Date {
+ unsigned day;
+ unsigned month;
+ unsigned year;
+};
+
+#endif /* _DATE */
diff --git a/Week10/Exercise03/Inventory.cpp b/Week10/Exercise03/Inventory.cpp
new file mode 100644
index 0000000..699997e
--- /dev/null
+++ b/Week10/Exercise03/Inventory.cpp
@@ -0,0 +1,73 @@
+#include "Inventory.h"
+
+void Inventory::free() {
+ delete[] products;
+}
+
+void Inventory::copyFrom(const Inventory& other) {
+ productsCount = other.productsCount;
+ productsAlloc = other.productsAlloc;
+
+ products = new Product[productsAlloc];
+ for (unsigned i = 0; i < productsCount; ++i)
+ products[i] = other.products[i];
+}
+
+void Inventory::resize() {
+ productsAlloc = productsAlloc == 0 ? 8 : productsAlloc * 2;
+ Product* productsLarger = new Product[productsAlloc];
+
+ for (unsigned i = 0; i < productsCount; ++i)
+ productsLarger[i] = products[i];
+
+ delete[] products;
+ products = productsLarger;
+}
+
+Inventory::Inventory() : products(), productsCount(), productsAlloc()
+{ }
+
+Inventory::~Inventory() {
+ free();
+}
+
+Inventory::Inventory(const Inventory& other) {
+ copyFrom(other);
+}
+
+Inventory& Inventory::operator=(const Inventory& other) {
+ if (this != &other) {
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+Inventory::Inventory(Inventory&& other) {
+ products = other.products;
+ productsCount = other.productsCount;
+ productsAlloc = other.productsAlloc;
+
+ other.products = nullptr;
+ other.productsAlloc = other.productsCount = 0;
+}
+
+Inventory& Inventory::operator=(Inventory&& other) {
+ if (this != &other) {
+ free();
+
+ products = other.products;
+ productsCount = other.productsCount;
+ productsAlloc = other.productsAlloc;
+
+ other.products = nullptr;
+ other.productsAlloc = other.productsCount = 0;
+ }
+ return *this;
+}
+
+void Inventory::AddProduct(const Product& product) {
+ if (productsCount >= productsAlloc)
+ resize();
+ products[productsCount++] = product;
+}
diff --git a/Week10/Exercise03/Inventory.h b/Week10/Exercise03/Inventory.h
new file mode 100644
index 0000000..7f5eeca
--- /dev/null
+++ b/Week10/Exercise03/Inventory.h
@@ -0,0 +1,36 @@
+#ifndef _INVENTORY
+#define _INVENTORY
+
+const unsigned PRODUCT_NAME_LENGTH = 1024;
+
+struct Product {
+ char name[PRODUCT_NAME_LENGTH];
+ unsigned quantity;
+};
+
+class Inventory {
+protected:
+ Product* products;
+ unsigned productsCount;
+ unsigned productsAlloc;
+
+private:
+ void free();
+ void copyFrom(const Inventory& other);
+
+ void resize();
+
+public:
+ Inventory();
+ ~Inventory();
+ Inventory(const Inventory& other);
+ Inventory& operator=(const Inventory& other);
+
+ Inventory(Inventory&& other);
+ Inventory& operator=(Inventory&& other);
+
+protected:
+ void AddProduct(const Product& product);
+};
+
+#endif /* _INVENTORY */
diff --git a/Week10/Exercise03/Shop.cpp b/Week10/Exercise03/Shop.cpp
new file mode 100644
index 0000000..4ed8ce3
--- /dev/null
+++ b/Week10/Exercise03/Shop.cpp
@@ -0,0 +1,91 @@
+#include "Shop.h"
+#include <cstring>
+#include <utility>
+
+void Shop::free() {
+ delete[] sales;
+}
+
+void Shop::copyFrom(const Shop& other) {
+ salesAlloc = other.salesAlloc;
+ salesCount = other.salesCount;
+
+ sales = new Sale[salesAlloc];
+ for (unsigned i = 0; i < salesCount; ++i)
+ sales[i] = other.sales[i];
+}
+
+void Shop::resize() {
+ salesAlloc = salesAlloc == 0 ? 8 : salesAlloc * 2;
+ Sale* salesLarger = new Sale[salesAlloc];
+
+ for (unsigned i = 0; i < salesCount; ++i)
+ salesLarger[i] = sales[i];
+
+ delete[] sales;
+ sales = salesLarger;
+}
+
+Shop::Shop() : Inventory(), sales(), salesCount(), salesAlloc()
+{ }
+
+Shop::~Shop() {
+ free();
+}
+
+Shop::Shop(const Shop& other) : Inventory(other) {
+ copyFrom(other);
+}
+
+Shop& Shop::operator=(const Shop& other) {
+ if (this != &other) {
+ Inventory::operator=(other);
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+Shop::Shop(Shop&& other) : Inventory(std::move(other)) {
+ sales = other.sales;
+ salesCount = other.salesCount;
+ salesAlloc = other.salesAlloc;
+
+ other.sales = nullptr;
+ other.salesAlloc = other.salesCount = 0;
+}
+
+Shop& Shop::operator=(Shop&& other) {
+ if (this != &other) {
+ Shop::operator=(std::move(other));
+
+ free();
+
+ sales = other.sales;
+ salesCount = other.salesCount;
+ salesAlloc = other.salesAlloc;
+
+ other.sales = nullptr;
+ other.salesAlloc = other.salesCount = 0;
+ }
+ return *this;
+}
+
+bool Shop::Purchase(const Sale& sale) {
+ unsigned productIndex = 0;
+ while (productIndex < productsCount &&
+ strcmp(sale.productName, products[productIndex].name) != 0)
+ {
+ ++productIndex;
+ }
+
+ if (productIndex == productsCount || products[productIndex].quantity >= sale.quantity)
+ return false;
+
+ if (salesCount >= salesAlloc)
+ resize();
+ sales[salesCount++] = sale;
+
+ products[productIndex].quantity -= sale.quantity;
+ return true;
+}
diff --git a/Week10/Exercise03/Shop.h b/Week10/Exercise03/Shop.h
new file mode 100644
index 0000000..ce1c8de
--- /dev/null
+++ b/Week10/Exercise03/Shop.h
@@ -0,0 +1,35 @@
+#ifndef _SHOP
+#define _SHOP
+
+#include "Inventory.h"
+#include "Date.h"
+
+struct Sale {
+ char productName[PRODUCT_NAME_LENGTH];
+ unsigned quantity;
+ Date date;
+};
+
+class Shop : public Inventory {
+ Sale* sales;
+ unsigned salesCount;
+ unsigned salesAlloc;
+
+ void free();
+ void copyFrom(const Shop& other);
+
+ void resize();
+
+public:
+ Shop();
+ ~Shop();
+ Shop(const Shop& other);
+ Shop& operator=(const Shop& other);
+
+ Shop(Shop&& other);
+ Shop& operator=(Shop&& other);
+
+ bool Purchase(const Sale& sale);
+};
+
+#endif /* _SHOP */
diff --git a/Week10/Exercise03/Warehouse.cpp b/Week10/Exercise03/Warehouse.cpp
new file mode 100644
index 0000000..2ce5cca
--- /dev/null
+++ b/Week10/Exercise03/Warehouse.cpp
@@ -0,0 +1,94 @@
+#include "Warehouse.h"
+#include <cstring>
+#include <utility>
+
+void Warehouse::free() {
+ delete[] deliveries;
+}
+
+void Warehouse::copyFrom(const Warehouse& other) {
+ deliveriesAlloc = other.deliveriesAlloc;
+ deliveriesCount = other.deliveriesCount;
+
+ deliveries = new Delivery[deliveriesAlloc];
+ for (unsigned i = 0; i < deliveriesCount; ++i)
+ deliveries[i] = other.deliveries[i];
+}
+
+void Warehouse::resize() {
+ deliveriesAlloc = deliveriesAlloc == 0 ? 8 : deliveriesAlloc * 2;
+ Delivery* deliveriesLarger = new Delivery[deliveriesAlloc];
+
+ for (unsigned i = 0; i < deliveriesCount; ++i)
+ deliveriesLarger[i] = deliveries[i];
+
+ delete[] deliveries;
+ deliveries = deliveriesLarger;
+}
+
+Warehouse::Warehouse() : Inventory(), deliveries(), deliveriesCount(), deliveriesAlloc()
+{ }
+
+Warehouse::~Warehouse() {
+ free();
+}
+
+Warehouse::Warehouse(const Warehouse& other) : Inventory(other) {
+ copyFrom(other);
+}
+
+Warehouse& Warehouse::operator=(const Warehouse& other) {
+ if (this != &other) {
+ Inventory::operator=(other);
+ free();
+ copyFrom(other);
+ }
+ return *this;
+}
+
+Warehouse::Warehouse(Warehouse&& other) : Inventory(std::move(other)) {
+ deliveries = other.deliveries;
+ deliveriesCount = other.deliveriesCount;
+ deliveriesAlloc = other.deliveriesAlloc;
+
+ other.deliveries = nullptr;
+ other.deliveriesCount = other.deliveriesAlloc = 0;
+}
+
+Warehouse& Warehouse::operator=(Warehouse&& other) {
+ if (this != &other) {
+ Warehouse::operator=(std::move(other));
+
+ free();
+
+ deliveries = other.deliveries;
+ deliveriesCount = other.deliveriesCount;
+ deliveriesAlloc = other.deliveriesAlloc;
+
+ other.deliveries = nullptr;
+ other.deliveriesCount = other.deliveriesAlloc = 0;
+ }
+ return *this;
+}
+
+bool Warehouse::Receive(const Delivery& delivery) {
+ for (unsigned i = 0; i < delivery.productsCount; ++i) {
+ unsigned productIndex = 0;
+ while (productIndex < productsCount &&
+ strcmp(delivery.products[i].name, products[productIndex].name) != 0)
+ {
+ ++productIndex;
+ }
+
+ if (productIndex == productsCount)
+ AddProduct(delivery.products[i]);
+ else
+ products[i].quantity += delivery.products[i].quantity;
+ }
+
+ if (deliveriesCount >= deliveriesAlloc)
+ resize();
+ deliveries[deliveriesCount++] = delivery;
+
+ return true;
+}
diff --git a/Week10/Exercise03/Warehouse.h b/Week10/Exercise03/Warehouse.h
new file mode 100644
index 0000000..b71d08c
--- /dev/null
+++ b/Week10/Exercise03/Warehouse.h
@@ -0,0 +1,36 @@
+#ifndef _WAREHOUSE
+#define _WAREHOUSE
+
+#include "Inventory.h"
+#include "Date.h"
+
+struct Delivery {
+ Product products[8];
+ unsigned productsCount;
+ Date date;
+ unsigned trackingNumber;
+};
+
+class Warehouse : public Inventory {
+ Delivery* deliveries;
+ unsigned deliveriesCount;
+ unsigned deliveriesAlloc;
+
+ void free();
+ void copyFrom(const Warehouse& other);
+
+ void resize();
+
+public:
+ Warehouse();
+ ~Warehouse();
+ Warehouse(const Warehouse& other);
+ Warehouse& operator=(const Warehouse& other);
+
+ Warehouse(Warehouse&& other);
+ Warehouse& operator=(Warehouse&& other);
+
+ bool Receive(const Delivery& delivery);
+};
+
+#endif /* _WAREHOUSE */
diff --git a/Week10/README.md b/Week10/README.md
new file mode 100644
index 0000000..22f1a20
--- /dev/null
+++ b/Week10/README.md
@@ -0,0 +1,3 @@
+# Задачи
+
+<https://syndamia.com/teaching/oop-2025/week10/>