From 8af74b1eeed52119ecaaf57ff6779edbc219c34b Mon Sep 17 00:00:00 2001 From: Angel Dimitriev Date: Tue, 17 May 2022 20:15:51 +0300 Subject: Update README.MD --- Sem. 12/README.MD | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) 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 +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 +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 + +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 + +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; +} + + ``` -- cgit v1.3.1-23-gd82d