diff options
1 files changed, 198 insertions, 0 deletions
| -rw-r--r-- | Sem. 12/README.MD | 198 |
diff --git a/Sem. 12/README.MD b/Sem. 12/README.MD index e69de29..7835c36 100644 --- a/Sem. 12/README.MD +++ b/Sem. 12/README.MD @@ -0,0 +1,198 @@ +# Статично и динамично свързване. Виртуални функции. Полиморфизъм. Абстрактни класове.
+#### Статично и динамично свързване. Виртуални функции.
+Пример за **статично** свързване:
+```c++
+#include <iostream>
+using namespace std;
+
+struct A
+{
+ void f() const
+ {
+ std::cout << "A::f()" << std::endl;
+ }
+};
+
+struct B : public A
+{
+ void f() const
+ {
+ std::cout << "B::f()" << std::endl;
+ }
+};
+
+int main()
+{
+ B* bPtr = new B();
+
+ A* aPtr = bPtr;
+
+ bPtr->f(); // B::f()
+ aPtr->f(); // A::f()
+}
+ ```
+
+ - **Статично** свързване - изборът на функцията, която трябва да се изпълни става **по време на компилация**.
+ - **Динамично** свързване – изборът на функцията, която трябва да се изпълни става **по време на изпълнение на програмата**.
+
+```c++
+#include <iostream>
+using namespace std;
+
+struct A
+{
+ virtual void f() const
+ {
+ std::cout << "A::f()" << std::endl;
+ }
+};
+
+struct B : public A
+{
+ void f() const
+ {
+ std::cout << "B::f()" << std::endl;
+ }
+};
+
+int main()
+{
+ А* ptrs[2];
+ ptrs[0] = new A();
+ ptrs[1] = new B();
+
+ ptrs[0]->f(); // B::f()
+ ptrs[1]->f(); // B::f()
+}
+ ```
+#### Полиморфизъм
+Едни и същи действия се реализират по различен начин в
+зависимост от обектите, върху които се прилагат.
+
+ - Действията се наричат полиморфни.
+ - Реализира се чрез виртуални функции.
+ - Класовете, върху които ще се прилага, трябва да имат общ родител или прародител, т.е. да са наследници на един и същ клас.
+ - В класа се дефинира виртуален метод, съответстващ на полиморфното действие.
+ - Всеки клас предефинира или не виртуалния метод.
+ - Активирането става чрез указател към базов клас, на който може да се присвоят адресите на обекти на който и да е от базовите класове от йерархията
+
+**Важно!** При полиморфна йерархия ще изтриваме обектите чрез указатели от базовия клас. За да се извикват правилните деструкори задължително **деструкторът на базовият клас** трябва е деклариран като виртуален!
+```c++
+#include<iostream>
+
+struct Animal
+{
+ virtual void sayHello() const
+ {
+ std::cout << "Hello, I am a random animal" << std::endl;
+ }
+
+ virtual ~Animal(){} //!!!
+};
+struct Dog : public Animal
+{
+ void sayHello() const override
+ {
+ std::cout << "Hello, I am a dog!" << std::endl;
+ }
+};
+
+struct Cat : public Animal
+{
+ void sayHello() const override
+ {
+ std::cout << "Hello, I am a cat!" << std::endl;
+ }
+};
+
+struct Mouse : public Animal
+{
+};
+
+int main()
+{
+ Animal** animals = new Animal*[3];
+
+ animals[0] = new Dog();
+ animals[1] = new Cat();
+ animals[2] = new Mouse();
+
+
+ //from base-class pointer
+ animals[0]->sayHello(); // Hello, I am a dog!
+ animals[1]->sayHello(); // Hello, I am a cat!
+ animals[2]->sayHello(); // Hello, I am a random animal!
+
+ delete animals[0], animals[1], animals[2];
+ delete[] animals;
+}
+
+ ```
+ #### Абстрактен клас
+
+
+ - Чисто виртуална функция (**pure virtual function**) - вруална функция без тяло.
+ - Клас е **абстрактен**, ако в него има поне една **чисто виртуална функция**.
+
+Тогава класът е предназначен единствено за наследяване и няма да може да създаваме обекти от него.
+Така във всеки наследник ще трябва да се разпише имплементация на функцията. Ако някой наследник няма собствена имплементация, то и той става абстрактен клас.
+
+```c++
+#include<iostream>
+
+struct Animal
+{
+ virtual void sayHello() const = 0;
+
+
+ virtual ~Animal(){} //!!!
+};
+struct Dog : public Animal
+{
+ void sayHello() const override
+ {
+ std::cout << "Hello, I am a dog!" << std::endl;
+ }
+};
+
+struct Cat : public Animal
+{
+ void sayHello() const override
+ {
+ std::cout << "Hello, I am a cat!" << std::endl;
+ }
+};
+
+struct Mouse : public Animal
+{
+ void sayHello() const override
+ {
+ std::cout << "Hello, I am a mouse!" << std::endl;
+ }
+};
+
+struct PrehistoricAnimal : public Animal
+{};
+
+int main()
+{
+ // Animal* pa1 = new Animal(); No! Animal is an abstract class!
+ // Animal* pa2 = new PrehistoricAnimal(); No! PrehistoricAnimal is also an abstract class!
+
+ Animal** animals = new Animal*[3];
+
+ animals[0] = new Dog();
+ animals[1] = new Cat();
+ animals[2] = new Mouse();
+
+
+ //from base-class pointer
+ animals[0]->sayHello(); // Hello, I am a dog!
+ animals[1]->sayHello(); // Hello, I am a cat!
+ animals[2]->sayHello(); // Hello, I am a random animal!
+
+ delete animals[0], animals[1], animals[2];
+ delete[] animals;
+}
+
+ ```
|
