# Задачи - ООП, Седмица 8, 11.04.2024 \n GitHub classroom: [url https://classroom.github.com/a/7d0MBjcK classroom.github.com/a/7d0MBjcK] ## Преговорни ### Задача 1 - Голяма петица .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise1.cpp Решение] Имплементирайте клас `[StreetList]`, който запазва имената на улици (низове с произволна дължина) в динамичен масив. Може да се добавят нови имена в края на списъка, като съответния (вътрешен) масив трябва да се уголеми. Имплементирайте голяма петица за класа. ### Задача 2 - Файлове и класове .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise2.cpp Решение] Имплементирайте клас `[Person]`, който запазва трите имена (низове с произволна дължина) и идентификационния номер (цяло неотрицателно число) на човек. Имплементирайте голяма петица. Имплементирайте методи `[SaveText]` и `[LoadText]`, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от =[текстови]= файл с подадено име. Аналогично имплементирайте `[SaveBinary]` и `[LoadBinary]`, които работят с =[двоични]= файлове. ## Лесни ### Задача 3 .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise3.hpp Решение] Имплементирайте шаблонната структура `[Pair]`, която приема два типа и запазва по една стойност от всеки тип. ### Задача 4 .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise4.cpp Решение] Имплементирайте клас `[FloatArray]`, който съдържа списък с числа с плаваща запетая. Може да добавяте нови числа в края на този списък. Имплементирйате голяма петица. Имплементирайте оператори: .bulleted - += и +, които конкатенират два FloatArray-я. += вмъква елементите от десния масив в края на левия, + връща нов масив в който първо са елементите от левия масив и след тях са тези от десния. - += и +, които приемат FloatArray и число (с плаваща запетая) и го прибавят към всеки елемент на FloatArray-я - [], които връщат референция към елементът на подадения индекс. При невалиден хвърлят грешка. - == и !=, които сравняват два FloatArray-я покомпонентно. Ако се различават по брой елементи или ако имат две различни стойности на еднакъв индекс, тогава не са равни. - <<, който вмъква всички стойности в подадения поток, разделени с шпация - >>, който презаписва всички стойности, разделени с шпация, четейки от подадени поток ### Задача 5 .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise5.hpp Решение] Имплементирайте класът и неговите оператори от предходната задача като темплейтен (шаблонен) клас с име `[DynamicArray]`. Очевидно шаблонния тип определя типа на списъка с елементи. ### Задача 6 .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise6.cpp Решение] Имплементирайте клас `[NumberInput]`, който запазва целочислена стойност. В конструктора се подава минимална и максимална възможна стойност, след това (все още в конструктора) се изкарва на екрана съответно съобщение и се приема потребителски вход. Ако той не е валиден или е извън подадения обхват, трябва да хвърлите грешка. В main създайте обект от този клас. Ако се хвърли грешка, прихванете я, изкарайте на екрана съответното съобщение и пробвайте пак. Това се повтаря докато обекта не е успешно създаден, след което изкарвате въведената стойност по две. ### Задача 7 .solution-link [url https://github.com/Syndamia/oop-2023-solutions/blob/main/week08/Exercise7.cpp Решение] Имплементирайте клас `[UserError]`, чиято употреба е да се хвърля като грешка. За тази цел нека да запазва два низа, които се приемат в конструктора: името на клас и името на член-данната. Имплементирайте голяма петица и оператор<<, който изкарва съобщение с информация за класа и член-данната в подадения поток. Следете бройката на създадени `[UserError]` инстанции в самия клас (статична променлива) и имплементирате нужната (статична) член-функция, която връща този брой. Преобразувайте последната задача, така че да хвърля грешка от този клас. В края на програмата изкарайте колко грешки са се хвърлили =[използвайки статичните членове на UserError]=. ## Трудни задачи ### Задача 8 Имплементирайте шаблонен клас `[UserInput]`, който запазва стойност от подадения тип. Ако типа е указател, тогава заделяте динамична памет за един такъв елемент. За проверка на типа използвайте [url https://en.cppreference.com/w/cpp/language/partial_specialization partial template specialization]. В шаблона (`[template <...>]`) се приема указател към валидираща функция, която приема стойността от съответния тип и връща булева стойност. В конструктора се приема от входа нужната стойност и ако стойността е неуспешно приета или валидиращата функция върне false, тогава хвърляте грешка. Ако типа е указател, не забравяйте да освободите паметта. В класа следете статично за броя пъти когато е хвърлена грешка. ### Задача 9 .important В тази задача се изикват помощни класове, прочетете цялото условие преди имплементиране! Имплементирайте шаблонен клас `[Dictionary]`, който запазва два динамично-заделени масива: първия е със стойност от подадения тип, втория е с низове. Низовете ще се използват за индексиране, вместо числа. Разбира се, очаквайте да може да се уразмерява. Имплементирайте голяма петица. Имплементирайте оператор: :bulleted - <<=, който вмъква всички стойности от десния `[Dictionary]` в левия - [], който приема низ и връща референция "към" стойността. Ако няма записана стойност на съответния индекс, тогава връщате референция в която може да се запише стойност. - [], който приема число, което се конвертира до низ и работи както предходния оператор - [], който приема низове (или числа), разделени със запетая и връща "масив" само с тези стойности - delete, който приема стойност, върната от оператор[] и "премахва" съответната стойност от `[Dictionary]` - префиксен++, префиксен+ и префиксен-, които ще се използват за итериране. .bulleted - ++ връща инкрементира индекса на сегашната стойност. Ако индекса е равен на броя запазени стойности, тогава става нула. По подразбиране индекса е броя. Връща true ако след инкрементиране индекса не е броя. - + връща референция към стойността на сегашния индекс - - връща сегашния (низов) индекс - ->, такъв че можем да правим `[a->(&func1)->(&func2)]` и `[a->[&func3]->[&func4]]`.\n Върху всяка двойка индекс-стойност се прилагат &func1 и &func2 (приемат индекс и стойност като параметри), които връщат нова стойност, заместваща сегашната.\n &func3, &func4 аналогично приемат индекс и стойност, но връщат нов индекс. В края на задачата трябва да можете да правите: :code_c++ int doubleUp(const char* index, int value) { return value * 2; } int sumIndexValue(const char* index, int value) { return atoi(index) + value; } const char* indToName(const char* index, int value) { if (strcmp(index, "2")) { return "two"; } return index; } int main() { Dictionary a; a["first"] = 8; a[2] = 13; a[89] = -68; Dictionary b; b["wow"] = 99; b["nth"] = 773; a <<= b; /* някакъв тип */ two = a["first", 2]; delete a["wow"]; a->(&doubleUp)->(&sumIndexValue)->[&indToName]; while (++a) { std::cout << +a << " at " << -a << ","; /* Ще изкара на конзолата: * 16 at first,52 at two,-12104 at 89,1546 at nth, */ } }