Задачи - ООП, Седмица 8, 11.04.2024

GitHub classroom: classroom.github.com/a/7d0MBjcK

Преговорни

Задача 1 - Голяма петица

< Решение >

Имплементирайте клас StreetList, който запазва имената на улици (низове с произволна дължина) в динамичен масив. Може да се добавят нови имена в края на списъка, като съответния (вътрешен) масив трябва да се уголеми.

Имплементирайте голяма петица за класа.

Задача 2 - Файлове и класове

< Решение >

Имплементирайте клас Person, който запазва трите имена (низове с произволна дължина) и идентификационния номер (цяло неотрицателно число) на човек. Имплементирайте голяма петица.

Имплементирайте методи SaveText и LoadText, които съответно записват и четат (тоест член-данните стават равни на тези от файла) данните си в/от текстови файл с подадено име. Аналогично имплементирайте SaveBinary и LoadBinary, които работят с двоични файлове.

Лесни

Задача 3

< Решение >

Имплементирайте шаблонната структура Pair, която приема два типа и запазва по една стойност от всеки тип.

Задача 4

< Решение >

Имплементирайте клас FloatArray, който съдържа списък с числа с плаваща запетая. Може да добавяте нови числа в края на този списък. Имплементирйате голяма петица.

Имплементирайте оператори:

Задача 5

< Решение >

Имплементирайте класът и неговите оператори от предходната задача като темплейтен (шаблонен) клас с име DynamicArray. Очевидно шаблонния тип определя типа на списъка с елементи.

Задача 6

< Решение >

Имплементирайте клас NumberInput, който запазва целочислена стойност. В конструктора се подава минимална и максимална възможна стойност, след това (все още в конструктора) се изкарва на екрана съответно съобщение и се приема потребителски вход. Ако той не е валиден или е извън подадения обхват, трябва да хвърлите грешка.

В main създайте обект от този клас. Ако се хвърли грешка, прихванете я, изкарайте на екрана съответното съобщение и пробвайте пак. Това се повтаря докато обекта не е успешно създаден, след което изкарвате въведената стойност по две.

Задача 7

< Решение >

Имплементирайте клас UserError, чиято употреба е да се хвърля като грешка. За тази цел нека да запазва два низа, които се приемат в конструктора: името на клас и името на член-данната.

Имплементирайте голяма петица и оператор<<, който изкарва съобщение с информация за класа и член-данната в подадения поток. Следете бройката на създадени UserError инстанции в самия клас (статична променлива) и имплементирате нужната (статична) член-функция, която връща този брой.

Преобразувайте последната задача, така че да хвърля грешка от този клас. В края на програмата изкарайте колко грешки са се хвърлили използвайки статичните членове на UserError.

Трудни задачи

Задача 8

Имплементирайте шаблонен клас UserInput, който запазва стойност от подадения тип. Ако типа е указател, тогава заделяте динамична памет за един такъв елемент. За проверка на типа използвайте partial template specialization.

В шаблона (template <...>) се приема указател към валидираща функция, която приема стойността от съответния тип и връща булева стойност. В конструктора се приема от входа нужната стойност и ако стойността е неуспешно приета или валидиращата функция върне false, тогава хвърляте грешка. Ако типа е указател, не забравяйте да освободите паметта.

В класа следете статично за броя пъти когато е хвърлена грешка.

Задача 9

important В тази задача се изикват помощни класове, прочетете цялото условие преди имплементиране!

Имплементирайте шаблонен клас Dictionary, който запазва два динамично-заделени масива: първия е със стойност от подадения тип, втория е с низове. Низовете ще се използват за индексиране, вместо числа. Разбира се, очаквайте да може да се уразмерява. Имплементирайте голяма петица.

Имплементирайте оператор:

В края на задачата трябва да можете да правите:

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<int> a;
    a["first"] = 8;
    a[2] = 13;
    a[89] = -68;

    Dictionary<int> 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,
         */
    }
}