diff options
feat(Week10): Add solutions
21 files changed, 839 insertions, 0 deletions
| -rw-r--r-- | Week10/Exercise01/Student.cpp | 5 | ||||
| -rw-r--r-- | Week10/Exercise01/Student.h | 14 | ||||
| -rw-r--r-- | Week10/Exercise01/Teacher.cpp | 5 | ||||
| -rw-r--r-- | Week10/Exercise01/Teacher.h | 14 | ||||
| -rw-r--r-- | Week10/Exercise01/User.cpp | 6 | ||||
| -rw-r--r-- | Week10/Exercise01/User.h | 14 | ||||
| -rw-r--r-- | Week10/Exercise02/CombustionVehicle.cpp | 69 | ||||
| -rw-r--r-- | Week10/Exercise02/CombustionVehicle.h | 27 | ||||
| -rw-r--r-- | Week10/Exercise02/ElectricVehicle.cpp | 79 | ||||
| -rw-r--r-- | Week10/Exercise02/ElectricVehicle.h | 31 | ||||
| -rw-r--r-- | Week10/Exercise02/Vehicle.cpp | 74 | ||||
| -rw-r--r-- | Week10/Exercise02/Vehicle.h | 66 | ||||
| -rw-r--r-- | Week10/Exercise02/main.cpp | 57 | ||||
| -rw-r--r-- | Week10/Exercise03/Date.h | 10 | ||||
| -rw-r--r-- | Week10/Exercise03/Inventory.cpp | 73 | ||||
| -rw-r--r-- | Week10/Exercise03/Inventory.h | 36 | ||||
| -rw-r--r-- | Week10/Exercise03/Shop.cpp | 91 | ||||
| -rw-r--r-- | Week10/Exercise03/Shop.h | 35 | ||||
| -rw-r--r-- | Week10/Exercise03/Warehouse.cpp | 94 | ||||
| -rw-r--r-- | Week10/Exercise03/Warehouse.h | 36 | ||||
| -rw-r--r-- | Week10/README.md | 3 |
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/> |
