| Name | Size | |
|---|---|---|
| .. | ||
| Complex | 114 B | log stats plain |
| Nvector | 210 B | log stats plain |
| README.md | 5.5 KiB | log stats plain blame |
Предефиниране на оператори. Приятелски класове и функции. Mutable член-данни.
Oператори
Видове оператори.
в C++ има два вида оператори:
- Унарни (на един аргумент)
- Бинарни (на два аргумента)
Операторите се характеризират с:
- Приоритет
- Асоциативност
- Позиция на оператора спярмо аргумента - префиксен, инфиксен и суфиксен
Списъка на операторите в C++:
| Оператор | Асоциативност |
|---|---|
| () [] -> . ++ - - | лявоасоциативен |
| + - ! ~ ++ - - (type)* & sizeof | дясноасоциативен |
| * / % | лявоасоциативен |
| + - | лявоасоциативен |
| << >> | лявоасоциативен |
| < <= > >= | лявоасоциативен |
| == != | лявоасоциативен |
| & | лявоасоциативен |
| ^ | лявоасоциативен |
| | | лявоасоциативен |
| && | лявоасоциативен |
| || | лявоасоциативен |
| ?: | дясноасоциативен |
| = += -= *= /= %= >>= <<= &= ^= | дясноасоциативен |
Предефиниране на оператор (пример)
Complex& Complex::operator+=(const Complex& other)
{
real += other.real;
im += other.im;
return *this;
}
```
Вече може да правим следното:
```c++
int main()
{
Complex c(1,3); //1 + 3i;
Complex c2(10,20) // 10 + 2i;
c += c2 // now c is 11 + 5i
}
```
При предефинирането на оператор **не могат** да се променят *приоритетът*, *асоциативността*, броят и позицията на *аргументите* му.
## Приятелски класове и приятелски функции
Декларират се с на запазената дума **friend** пред прототипа на функцията.
Даденият friend-клас/фунцкия има достъп до всички компоненти на класа.
Т.е. всички членове на класа са public за friend-класовете/функциите приятели.
### Приятелски функции (пример)
```c++
class Complex
{
private:
double real;
double im;
public:
friend double getModulos(const Complex& other);
.
.
.
}
```
```c++
double getModulos(const Complex& other)
{
return sqrt((other.real – other.real) * (other.real – other.real) + (other.im – other.im ) * (other.im – other.im));
}
Mutable (пример)
Спецификатора mutable е приложен само в С++. Той позволява на член на обект да предефинира константността. Така mutable член на const обект не е const и може да бъде изменян. ```c++ struct Test { private: mutable int n; public: void f() const { n++; }
};
int main() { const Test t;
t.f();
} ```
Задачи
Задача 1: Реализирайте клас Nvector, който ще се използва за работа с математически вектор. Предефинирайте оператори със следната функционалност: - Събиране на вектори. - Изваждане на вектори. - Умножение на вектор със скалар. - Проверка дали два вектора са успоредни. - Проверка дали два вектора са перпендикулярни. - Взимане на дължина на вектор. - Достъп до произволен елемент на вектор. - Вход и изход от потоци.
```c++ int main() { Nvector v(4); cin >> v;
Nvector v2(4);
cin >> v;
Nvector result = v + v2;
cout << result << endl;
} ``` Релизирайте клас двумерната декартова координатна система, която приема 2 вектора, които са нейният базис. Реализрайте следните функции: - Връща вектор в базиса по подадени 2 координата. - По подаден вектор връща координатите му в базиса.
```c++ int main() { Nvector v(4); v[0] = 2; v[1] = 1;
Nvector v2(4);
v2[0] = 3;
v2[1] = 1;
twoDimCoordSystem s(v1, v2);
cout << s1.getVectorByCoordinates(7, 4); // [26, 11]
cout << s1.getCoordinatesByVector(7, 4); // [5, -1]
cout << result << endl;
} ```
Задача 2: Реализирайте клас ComplexNumber, който ще се използва за работа с комплексни числа. Предефинирайте оператори със следната функционалност: - Събиране на комплексни числа. - Изваждане на комплексни числа. - Умножение на комплексни числа. - Деление на комплексни числа - Вход и изход от потоци.
```c++
int main() { ComplexNumber c; cin >> c;
ComplexNumber c2;
cin >> c2;
ComplexNumber result = c2 / c;
cout << result << endl;
} ``` Задача 3: Релизирайте клас - множество(без повторение) от думи от малки/главни латински букви и цифри. В колекцията ви търсенето трябва да е с логаритмична сложност. Предефинирайте оператори:
- += и +. Събиране на две колекции.
- -= и -. От думите на лявата колекция, се премахват тези, които участват в дясната.
- [], който приема дума и връща дали стрингът е в колекцията (очакваме логаритмично време).
- *= за добавяне на дума
- /= за премахване на дума.
- << (поток за изход. Отпечатва всички думи в сортиран вид).
- >> (поток за вход. Приема думa, която да се добави в речника).
Важно! Копирането на стрингове е бавна операция! Помислете как да организирате данните, за да имате логаритмично търсене на дума и при добавяне на нова дума да правите минимален брой копирания на стрингове!
```c++
int main() { StringPool dict; ((dict = "Ivan") = "Petur") *= "Alex"; std::cout << dict << std::endl; // {Alex, Ivan, Petur} std::cout << dict["Alex"] << " " << dict["abc"] << std::endl; // 1 0
StringPool dict2;
((dict2 *= "Zebra") *= "Alex");
StringPool result = dict + dict2;
std::cout << result << std::endl; // {Alex, Ivan, Petur, Zebra}
StringPool result2 = dict - dict2;
std::cout << result2 << std::endl; // {Ivan, Petur}
"NewWOrd" >> result2;
result2 /= "NonExistingWord";
std::cout << result2 << std::endl; //{Ivan, NewWOrd, Petur}
"Job" >> result2;
std::cout << result2 << std::endl; //{Ivan, Job, NewWOrd, Petur}
} ```
