Summary Files Commits Branches @commit @diff @stats
path: root / src / teaching / oop-2025 / week11 / index.du
blob: ac154b67e4430219f8670e4d5a4a23a10843a707 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
'def title Задачи - ООП, Седмица 11, 29.04.2026
'def  desc Условията на задачите за упражнение.

# {title}

{pagenav 4 min;28 April 2026;29 April 2026}

## За решаване

### Задача 1

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise01}

Реализирайте шаблонен клас {` Pair}, който пази две стойности от типове {` T} и {` U}.
Реализирайте съотвените мутатори и селектори за константни и неконстантни обекти.

### Задача 2

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise02}

Реализирайте шаблонен клас {` Option}, който съхранява стойност от тип {` T}.

Нека конструкторите да {b не} са публични.
За създаване на обект, имплементирайте статични методи {` Some} и {` None}, първия от които приема стойност, а втория не приема нищо.

Целта е следната: ако един {` Option} е създаден чрез {` None}, тогава обозначаваме че няма стойност, а чрез {` Some} показваме че има стойност.
Идеята е аналогична на това когато един указател е {` nullptr} или не, но работи в по-общи случаи.

Имплементирайте методи:
.bulleted
- {` IsSome}, връща дали има стойност
- {` IsNone}, връща дали няма стойност
- {` Unwrap}, връща запазената стойност

### Задача 3

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise03}

Реализирайте шаблонен клас {` SharedPointer}, който пази динамично-заделен указател към тип {` T}.
Допълнително, класа следи за бройката свои {i инстанции}.

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

.note
Това е вид {url "smart pointer";https://en.wikipedia.org/wiki/Smart_pointer}: динамично-заделен указател който сам освобождава паметта си, без ние да пишем експлицитен {` delete}!\n
В C++ има и други видове smart pointer-и, като "unique pointer" (който е описан в {url Задача 6;#-6}).

Добър въведителен ресурс по темата е {url този;https://courses.cs.washington.edu/courses/cse333/24au/lectures/16-c++-smartptr.pdf}.

Реализирайте {` operator*} и {` operator->}, които съответстват на операциите върху запазения указател.
Тоест, {` *x} трябва да има един и същ ефект върху {` int*} и върху {` SharedPointer} от {` int*}.

.question
Как работи {` operator->}?

Имплементирайте също метод {` RefCount}, който връща броя копия.

Примерна употреба:
```cpp
void inc(SharedPointer<int> val) { // val е копие на y, бройката е 3
    *val++;
} // val се унищожава, бройката става 2
int main() {
    SharedPointer<int> x(new int); // Първа инстанция, бройката е 1
    SharedPointer<int> y = x;      // Копие, бройката е 2
    *x = 5;
    std::cout << *x << ' ' << *y << std::endl; // Показва "5 5"
    inc(y);
    std::cout << *x << ' ' << *y << std::endl; // Показва "6 6"
} // x и y се унищожават, бройката става 0 и паметта се освобождава

### Задача 4

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise04}

Реализирайте шаблонен клас {` Vector}, който съхранява неограничено и оразмеряемо количество от обекти {` T}.

Освен голяма петица, реализирайте член-функции:
.bulleted
- {` Count}, която връща броя елементи
- {` PushBack}, която добавя елемент в края на последователността.
  Ако е нужно, уголемява заделеното количество памет.
- {` operator[]}, който връща референция към обекта на подаден индекс.
  Да бъде наличен при константни и не-константни обекти.
- {` operator+} който създава нов {` Vector} с елементите от първия и след това елементите от втория {` Vector}
- {` operator+=}, които добавя елементите на десния {` Vector} в края на левия

## За самоподготовка

### Задача 5

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise05}

Реализирайте клас {` DoubleVector}, който съхранява две неограничени и оразмеряеми количества от обекти, съответно от типове {` T} и {` U}.

Имплементирайте голяма петица и член-функциите от {url Задача 4;#-4}, обаче всяка трябва да е налична и за двете последователности от обекти.

### Задача 6

.solution-link {url Решение;https://github.com/Syndamia/oop-2025-solutions/tree/main/Week11/Exercise06}

Реализирайте шаблонен клас {` UniquePointer}, който пази указател към тип {` T}.
Класа трябва да осигури, че само един обект има този указател.
С други думи, {b не може да има копия}!

Реализирайте {` operator*} и {` operator->}, които съответстват на операциите върху запазения указател (т.е. {` *x} трябва да има същия ефект, без значение дали работим с {` int*} или {` SharedPointer}, който съхранява {` int*}).