Skip to content

Commit 1807596

Browse files
committed
Presentation updated
1 parent cbe7074 commit 1807596

File tree

1 file changed

+67
-40
lines changed

1 file changed

+67
-40
lines changed

module2/presentation.md

Lines changed: 67 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ ___
706706
707707
Co to za słowa? Co one robią? O tym w kolejnej lekcji ;)
708708
709-
Zostawiamy was z tym niedopowiedzeniem, abyście sami zechcieli poszukać o tym informacji lub przejrzeli wideo pana Zelenta.
709+
Zostawiamy was z tym niedopowiedzeniem, abyście sami zechcieli poszukać o tym informacji lub przejrzeli wideo pana Zelenta. `virtual` tam znajdziecie, ale `override` nie, bo to zbyt nowa rzecz, bo weszła 9 lat temu ;)
710710
711711
___
712712
@@ -736,17 +736,21 @@ int main() {
736736

737737
___
738738

739-
## Polimorfizm
739+
## Nadpisywanie metod - `override`
740740

741-
Wracając do przykładu o ptakach, klasy `Penguin`, `Hummingbird` oraz `Goose` to klasy pochodne, które dziedziczą po pewnych klasach bazowych jak `Bird`, `Flyable`, `Soundable`, `Swimmable` oraz przeciążają kilka ich metod jak:
741+
Wracając do przykładu o ptakach, klasy `Penguin`, `Hummingbird` oraz `Goose` to klasy pochodne, które dziedziczą po pewnych klasach bazowych jak `Bird`, `Flyable`, `Soundable`, `Swimmable` oraz nadpisują kilka ich metod jak:
742742

743743
* `void eat() override`
744744
* `void sleep() override`
745745
* `void makeSound() override`
746746
* `void fly() override`
747747
* `void swim() override`
748-
749-
Przeciążanie takich metod powoduje, że możemy zmienić nieco implementacje konkretnych metod:
748+
749+
Nadpisanie takich metod powoduje, że możemy zmienić ich implementacje
750+
751+
___
752+
753+
## `override`
750754

751755
```cpp
752756
class Soundable {
@@ -758,29 +762,33 @@ public:
758762
```cpp
759763
class Goose : public Soundable {
760764
public:
761-
// Override from Soundable
762765
void makeSound() override { std::cout << "Honk! Honk!"; }
763766
};
764767
```
765768

766769
```cpp
767770
class Hen : public Soundable {
768771
public:
769-
// Override from Soundable
770772
void makeSound() override { std::cout << "Cluck! Cluck!"; }
771773
};
772774
```
773775
774776
```cpp
775777
class Duck : public Soundable {
776778
public:
777-
// Override from Soundable
778779
void makeSound() override { std::cout << "Quack! Quack!"; }
779780
};
780781
```
781782

783+
___
784+
785+
## Wspólna klasa bazowa
786+
782787
Ponieważ wspólnym rodzicem wszystkich klas jest klasa `Soundable` możemy przechowywać w kontenerze wskaźniki typu `Soundable`.
783-
`std::vector<std::shared_ptr<Soundable>> birds_;`
788+
789+
```cpp
790+
std::vector<std::shared_ptr<Soundable>> birds_;
791+
```
784792

785793
### Jakie dane otrzymamy na wyjściu?
786794

@@ -790,68 +798,79 @@ birds_.push_back(std::make_shared<Goose>());
790798
birds_.push_back(std::make_shared<Hen>());
791799
birds_.push_back(std::make_shared<Duck>());
792800

793-
std::cout << birds_[0]->MakeSound() << '\n';
794-
std::cout << birds_[1]->MakeSound() << '\n';
795-
std::cout << birds_[2]->MakeSound() << '\n';
801+
std::cout << birds_[0]->makeSound() << '\n';
802+
std::cout << birds_[1]->makeSound() << '\n';
803+
std::cout << birds_[2]->makeSound() << '\n';
796804
```
797805

798-
Zjawisko, które właśnie obserwowaliśmy, nazywa się polimorfizmem.
799-
Polimorfizm pozwala funkcji przybrać różne formy jak na przykładzie.
800-
Dlatego, jeżeli utworzymy kolejno obiekty `Goose`, `Hen` i `Duck` w zależności
801-
od obiektu zostanie wywołana jego wersja metody `MakeSound`.
806+
___
807+
808+
## Polimorfizm
809+
810+
Zjawisko, które właśnie zaobserwowaliśmy, nazywa się polimorfizmem.
811+
812+
Polimorfizm pozwala funkcji przybrać różne formy (implementacje), tak jak na przykładzie.
813+
814+
Dlatego, jeżeli utworzymy kolejno obiekty `Goose`, `Hen` i `Duck` w zależności od obiektu zostanie wywołana jego wersja metody `makeSound`.
802815

803816
### Kto grał lub czytał Wiedźmina?
804817

818+
___
819+
820+
## Doppler :)
821+
805822
W uniwersum wykreowanym przez naszego rodzimego pisarza Andrzeja Sapkowskiego, występuje pewna
806823
intrygująca i ciekawa rasa zwana Dopplerami. Rasa ta potrafi przyjąć, postać różnych form życia,
807824
może stać się człowiekiem, elfem, krasnoludem. Zmienia w ten sposób swoje cechy jak głos, kolor włosów, a nawet ubranie!
808825
Pomimo że rasa ta jest typu Doppler, potrafi w różnych okolicznościach podszywać się pod inne rasy jak elf, krasnolud czy człowiek.
809826
Z punktu widzenia C++ nasz Doppler podlega zjawisku polimorfizmu.
810827

828+
___
829+
<!-- .slide: style="font-size: 0.9em" -->
830+
811831
```cpp
812832
class Doppler {
813833
public:
814-
virtual SayHallo() {
815-
std::cout << "I'm Doppler!";
816-
}
834+
virtual sayHello() { std::cout << "I'm Doppler!"; }
817835
};
818836

819837
class Dwarf : public Doppler {
820-
virtual SayHallo() {
821-
std::cout << "I'm Dwarf!";
822-
}
838+
public:
839+
virtual sayHello() { std::cout << "I'm Dwarf!"; }
823840
};
824841

825842
class Elf : public Doppler {
826-
virtual SayHallo() {
827-
std::cout << "I'm Elf!";
828-
}
843+
public:
844+
virtual sayHello() { std::cout << "I'm Elf!"; }
829845
};
830846

831847
class Human : public Doppler {
832-
virtual SayHallo() {
833-
std::cout << "I'm Human!";
834-
}
848+
public:
849+
virtual sayHello() { std::cout << "I'm Human!"; }
835850
};
836851

837852
int main() {
838853
std::shared_ptr<Doppler> doppler1 = std::make_shared<Dwarf>();
839854
std::shared_ptr<Doppler> doppler2 = std::make_shared<Elf>();
840855
std::shared_ptr<Doppler> doppler3 = std::make_shared<Human>();
841856

842-
std::cout << doppler1->SayHallo() << '\n';
843-
std::cout << doppler2->SayHallo() << '\n';
844-
std::cout << doppler3->SayHallo() << '\n';
857+
std::cout << doppler1->sayHello() << '\n';
858+
std::cout << doppler2->sayHello() << '\n';
859+
std::cout << doppler3->sayHello() << '\n';
845860
}
846861
```
847862
848863
<!-- TODO: Pokazać, że bez słowa virtual też kod się skompiluje, ale zachowa się inaczej -->
849864
850-
Jak widzimy, nasz Doppler może przyjąć różne formy i zachowywać się tak jak one. Pomimo że wskaźnik jest typu Doppler.
851-
Program dobrze wie, kiedy Doppler podszywa się pod człowieka, kiedy pod krasnoluda, a kiedy pod elfa.
865+
Jak widzimy, nasz Doppler może przyjąć różne formy i zachowywać się tak jak one. Wskaźnik jest typu Doppler, ale program dobrze wie, kiedy Doppler podszywa się pod człowieka, kiedy pod krasnoluda, a kiedy pod elfa.
866+
867+
___
868+
<!-- .slide: style="font-size: 0.9em" -->
869+
870+
## Wirtualne destruktory
852871
853872
Bardzo ważne w przypadku tworzenia metod wirtualnych i dziedziczenia jest tworzenie wirtualnych destruktorów.
854-
Jeżeli korzystamy z dobroci polimorfizmu i nie oznaczymy destruktor jako `virtual` lub w klasach pochodnych jako `override`, to destruktor ten nie zostanie wywołany.
873+
Jeżeli korzystamy z dobroci polimorfizmu i nie oznaczymy destruktor jako `virtual` to destruktor ten nie zostanie wywołany.
855874
856875
```cpp
857876
#include <iostream>
@@ -870,10 +889,12 @@ public:
870889
};
871890
872891
int main() {
873-
Child child;
892+
Child child; // ok, object on stack, not a pointer
874893
}
875894
```
876895

896+
___
897+
877898
```cpp
878899
#include <iostream>
879900
#include <memory>
@@ -893,13 +914,15 @@ public:
893914

894915
int main() {
895916
// Problem
896-
std::unique_ptr<Parent> child2 = std::make_unique<Child>();
917+
std::unique_ptr<Parent> child = std::make_unique<Child>();
897918

898-
// But shared_ptr will clenup propelry
919+
// But shared_ptr will cleanup properly
899920
std::shared_ptr<Parent> child2 = std::make_shared<Child>();
900921
}
901922
```
902923
924+
___
925+
903926
```cpp
904927
#include <iostream>
905928
#include <memory>
@@ -923,6 +946,7 @@ int main() {
923946
```
924947

925948
___
949+
<!-- .slide: style="font-size: 0.9em" -->
926950

927951
## Zmienne i funkcje statyczne
928952

@@ -949,7 +973,12 @@ int main() {
949973

950974
Nawet jeżeli obiekt zajmowałby dużo miejsca w pamięci a my chcielibyśmy tylko jego nazwę i tak musimy go utworzyć, ponieważ tylko na nim możemy zawołać metodę `getName()`.
951975

952-
Rozwiązaniem tej uciążliwości jest `static`. Co więcej, problem ten możemy rozwiązać na 2 sposoby:
976+
___
977+
<!-- .slide: style="font-size: 0.9em" -->
978+
979+
## `static`
980+
981+
Rozwiązaniem tej uciążliwości jest `static`. Co więcej, problem ten możemy rozwiązać na 2 sposoby. Nie musimy w ten sposób tworzyć specjalnie obiektu, aby dostać się do cechy klasy, jaką jest jej nazwa.
953982

954983
```cpp
955984
class Object {
@@ -972,8 +1001,6 @@ int main() {
9721001
}
9731002
```
9741003
975-
Nie musimy w ten sposób tworzyć specjalnie obiektu, aby dostać się do cechy klasy, jaką jest jej nazwa.
976-
9771004
<!-- TODO: Brakuje tu motywacji na jakimś konkretnym przykładzie -->
9781005
9791006
___

0 commit comments

Comments
 (0)