Website Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commit864e2176bb6733b2938e72e916b1ee52930883ca (patch)
Author
 Angel Dimitriev <angel_dimitriev@abv.bg>
2022-04-30 15:07:20 +0300
Committer
 GitHub <noreply@github.com>
2022-04-30 15:07:20 +0300
Filese3c8b8dfca4a42c0ad307f5adb8a695061ca6f78
Object-oriented_programming_FMI-864e2176bb6733b2938e72e916b1ee52930883ca.tar
Object-oriented_programming_FMI-864e2176bb6733b2938e72e916b1ee52930883ca.tar.gz
Object-oriented_programming_FMI-864e2176bb6733b2938e72e916b1ee52930883ca.zip
Parentf88a3b1b3cd4747a92c35f923d2db2ec9ecf5adc (diff)
Update README.md
1 files changed, 156 insertions, 0 deletions
-rw-r--r--Sem. 09/README.md156
diff --git a/Sem. 09/README.md b/Sem. 09/README.md
index 8b13789..53f3a32 100644
--- a/Sem. 09/README.md
+++ b/Sem. 09/README.md
@@ -1 +1,157 @@
+
+
+## Масиви от указатели към обекти. Изключения. Move семантики.
+Масиви от указатели към обекти.
+
+ ```c++
+class SomeCollection
+{
+ A** data;
+ //other things
+};
+ ```
+![enter image description here](https://i.ibb.co/YDCL2nr/pointer-Of-Pointers.png)
+##### Какви са ползите:
+
+ - Бързо разместване на обектите в колецкията - не се изисква да се копират. Само разместваме указателите
+ - Не се изисква същестуването на деф. контруктор на A.
+ - Възможно е да имаме "празна клетка", като се възползваме от възможната nullptr стойнот.
+
+
+#### Изключения
+![enter image description here](https://i.ibb.co/hDMRzMB/df-drawio-1.png)
+
+ - Защо е хубаво да извикваме .close() на потоците екпслицитно ?
+
+#### Move сменатики
+
+# Move семантики
+#### Подаване на стойност по референция
+```c++
+#include <iostream>
+using namespace std;
+
+void f(int& n)
+{
+ cout << n << endl;
+}
+int main()
+{
+ int number = 10;
+ f(number); // OK!
+ f(3); // Error!
+}
+ ```
+"Висящата" константа 3 **няма адрес в паметта**. За това подаването и като параметър на функцията f ще доведе до компилационна грешка.
+
+**&&** - за стойности без адрес в паметта
+```c++
+#include<iostream>
+using namespace std;
+
+void f(int& n)
+{
+ cout << n << endl;
+}
+int main()
+{
+ int number = 10;
+ f(number); // OK!
+ f(3); // Error!
+}
+ ```
+
+#### Пример за използването на &&
+```c++
+#include<iostream>
+using namespace std;
+
+void f(int&& n)
+{
+ cout << n << endl;
+}
+int main()
+{
+ int number = 10;
+ f(number); // Error!
+ f(3); // OK!
+}
+ ```
+Тук грешката възниква при подаването на променлива, която **има адрес в паметта.**
+#### lvalue и rvalue
+
+ - **lvalue** - обект, който заема някакво конкретно място в паметта. (стойността в паметта може да се модифицира)
+ - **rvalue** - обект, който не е *lvalue* .
+
+
+#### Излишни копия?
+Да разгледаме следният програмен фрагмент:
+
+```c++
+#include<iostream>
+#include<iostream>
+#include "Person.h"
+using namespace std;
+
+Person createPerson(const char* name, int age)
+{
+ Person p(name, age);
+
+ return p;
+}
+
+int main()
+{
+ Person p2("Petur",18);
+ p2 = createPerson("Ivan", 23);
+}
+ ```
+Тук се изпълняват следните функции на Person:
+
+ 1. Конструктор на Person (за p2)
+ 2. Конструктор за Person (на p).
+ 3. Копиращ конструктор (за *return p*)
+ 4. Деструктор (в края на функцията *createPerson*)
+ 5. Оператор = (за *p2 = create...* )
+ 6. Деструктор (в края на функцията *main*)
+
+Проблемът тук е, че правим излишни копия. Обектът създаден в *createPerson* **се копира два пъти докато се присвои** на p2.
+#### Move конструктор и move оператор =.
+За да избегнем излишните копия, може да "преместим" данните на обектът, който се създава във функцията, в данните на p2.
+```c++
+
+//Move constructor
+Person::Person(Person&& rhs)
+{
+ name = rhs.name;
+ age = rhs.age;
+
+ rhs.name = nullptr;
+}
+
+//Move operator=
+Person& Person::operator=(Person&& rhs)
+{
+ if (this != &rhs)
+ {
+ free();
+
+ name = rhs.name;
+ rhs.name = nullptr;
+ }
+ return *this;
+}
+ ```
+
+ Важно е да се обърне внимание, че тук данните **не се копират**, а се **местят**. Т.е приемаме, че rhs **няма да се използва след изпълнението на функцията.**
+ Сега при изпълнението на първоначално разгледания код:
+ 1. Конструктор на Person (за p2)
+ 2. Конструктор за Person (на p).
+ 3. **Move конструктор** (за *return p*)
+ 4. Деструктор (в края на функцията *createPerson*)
+ 5. **Move oператор =** (за *p2 = create...* )
+ 6. Деструктор (в края на функцията *main*)
+
+
+Т.е тук си спестихме 2 копия за динамичната памет в Person.