C++ - [4-7] Polimorfizm



Podobne dokumenty
Zaawansowane programowanie w języku C++ Programowanie obiektowe

Wykład V. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Programowanie obiektowe Wykład 6. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Programowanie 2. Język C++. Wykład 3.

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

TEMAT : KLASY DZIEDZICZENIE

Podstawy programowania w języku C++ Zadania - dziedziczenie i polimorfizm

Zaawansowane programowanie w C++ (PCP)

PARADYGMATY PROGRAMOWANIA Wykład 4

Wykład 9: Polimorfizm i klasy wirtualne

Wykład 9: Metody wirtualne i polimorfizm

Plik klasy. h deklaracje klas

Języki Programowania. Prowadząca: dr inż. Hanna Zbroszczyk. tel: Konsultacje: piątek:

dr inż. Jarosław Forenc

Programowanie obiektowe w języku

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Dziedziczenie. Ogólna postać dziedziczenia klas:

Dziedziczenie jednobazowe, poliformizm

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Projektowanie obiektowe. Roman Simiński Wzorce projektowe Wybrane wzorce strukturalne

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Instrukcja do pracowni specjalistycznej z przedmiotu. Obiektowe programowanie aplikacji

Programowanie obiektowe i zdarzeniowe

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

Programowanie 2. Język C++. Wykład 9.

Język C++ wykład VII. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VII. dr Jarosław Mederski. Spis.

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

Listy powiązane zorientowane obiektowo

Wprowadzenie do programowanie obiektowego w języku C++

Programowanie II. Lista 3. Modyfikatory dostępu plik TKLientBanku.h

Programowanie obiektowe. Dr hab. Inż. Marta Gładysiewicz-Kudrawiec Pokój 229 A1 Operatory new delete pliki-odczyt

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

Programowanie obiektowe Wykład 7. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/20

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 4. Karol Tarnowski A-1 p.

EGZAMIN PROGRAMOWANIE II (10 czerwca 2010) pytania i odpowiedzi

Zaawansowane programowanie w C++ (PCP)

EGZAMIN 2 (14 WRZEŚNIA 2015) JĘZYK C++

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 4. Karol Tarnowski A-1 p.

Szablony funkcji i szablony klas

Klasa dziedzicząca posiada wszystkie cechy klasy bazowej (plus swoje własne) dodawanie nowego kodu bez edycji (i ewentualnego wprowadzania

TEMAT : KLASY POLIMORFIZM

C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm. C++ - polimorfizm POLIMORFIZM

Stos liczb całkowitych

Identyfikacje typu na etapie. wykonania (RTTI)

Polimorfizm. dr Jarosław Skaruz

Funkcje. Spotkanie 5. Tworzenie i używanie funkcji. Przekazywanie argumentów do funkcji. Domyślne wartości argumentów

PARADYGMATY PROGRAMOWANIA Wykład 2

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

Programowanie obiektowe w języku C++ Zarządzanie procesami. dr inż. Jarosław Forenc. Przeładowanie (przeciążanie) operatorów

PROE wykład 4 pozostałe operatory, forward declaration, dziedziczenie. dr inż. Jacek Naruniec

Technologie i usługi internetowe cz. 2

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 20 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 32

Podstawy Programowania Obiektowego

C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie C++ - DZIEDZICZENIE.

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Wykład 8: klasy cz. 4

Wykład 5: Klasy cz. 3

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Programowanie obiektowe

Programowanie komputerowe. Zajęcia 7

Enkapsulacja, dziedziczenie, polimorfizm

Programowanie obiektowe w C++ Wykład 12

Materiały do zajęć VII

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Programowanie obiektowe

Aplikacje w środowisku Java

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Język C++ Programowanie obiektowe

Programowanie Obiektowe i C++

class Student Deklaracja klasy Osoba: Deklaracja klasy Student:

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Projektowanie obiektowe. Roman Simiński Polimorfizm

Szablony funkcji i klas (templates)

Dziedziczenie Dana jest klasa Punkt w pliku o nazwie Punkt.java:

Dziedziczenie. dr Jarosław Skaruz

Dziedziczenie jednobazowe, poliformizm, tablice wskaźników na obiekty

2.4 Dziedziczenie. 2.4 Dziedziczenie Przykłady programowania w C - kurs podstawowy

wykład V uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C++ klasy i obiekty wykład V dr Jarosław Mederski Spis Język C++ - klasy

Wstęp do programowania obiektowego, wykład 7

Programowanie obiektowe

Dziedziczenie. Tomasz Borzyszkowski

Abstrakcyjny typ danych

Podstawy Programowania Obiektowego

Języki i paradygmaty programowania Wykład 2. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/18

.NET Klasy, obiekty. ciąg dalszy

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

C++ - [1-3] Debugowanie w Qt Creator

Owad():waga(1),jadowitosc(false) {cout<<"konstruktor domyslny owada\n";}

Język C++ wykład VI. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VI. dr Jarosław Mederski.

Transkrypt:

Slajd 1 z 14 C++ - [4-7] Polimorfizm Nysa 2004-2013. Autor: Wojciech Galiński. wersja dnia 20 maja 2013 r.

Slajd 2 z 14 Polimorfizm i klasa polimorficzna POLIMORFIZM (cytat z Wikipedii) (wielopostaciowość) to mechanizmy pozwalające programiście używać wartości, zmiennych i podprogramów na kilka różnych sposobów. Inaczej mówiąc jest to możliwość wyabstrahowania wyrażeń od konkretnych typów. Z polimorfizmem mamy do czynienia podczas wywoływania wirtualnych funkcji składowych, ponieważ odpowiednia funkcja składowa jest wybierana niejawnie już podczas działania programu w zależności od typu obiektu, który ją wywołał. KLASA POLIMORFICZNA KLASA POLIMORFICZNA to klasa zawierająca wirtualne funkcje składowe.

Slajd 3 z 14 Pojęcie wirtualnej funkcji składowej WIRTUALNA FUNKCJA SKŁADOWA to funkcja, w której definicji znajduje się słowo virtual. Podczas wywoływania takiej funkcji (a więc już podczas działania programu) analizowany jest typ obiektu, który wywołał tę funkcję. Oto wzorzec definicji wirtualnej funkcji składowej (słowo virtual występuje w definicji klasy podstawowej i działa na definicje tej funkcji w klasach pochodnych): virtual dowolny_typ Klasa::nazwa_funkcji(argumenty) // ciało (treść) wirtualnej funkcji składowej

Slajd 4 z 14 Wirtualne funkcje składowe - ćwiczenie ĆWICZENIE 4.7.1: Wytłumacz działanie poniższego programu. Dopisz w odpowiednim miejscu słowo kluczowe virtual. class Osoba public: void przedstaw_sie() cout << "Ble ble ble\n"; ; class Polak: public Osoba public: string imie; void przedstaw_sie() cout << "Mam na imię " << imie << "\n"; ; class Niemiec: public Osoba public: string imie; void przedstaw_sie() cout << "Ich heiße " << imie << "\n"; ; class Anglik: public Osoba public: string imie; void przedstaw_sie() cout<< "My name is "<< imie<< "\n"; ; void przedstaw_sie(osoba &osoba) osoba.przedstaw_sie(); int main() Osoba os; os.przedstaw_sie(); Polak po; po.imie = "Jan"; po.przedstaw_sie(); Niemiec ni; ni.imie = "Klaus"; przedstaw_sie(ni); Anglik *wan = new Anglik(); wan->imie = "Elisabeth"; wan->przedstaw_sie(); delete wan; return 0;

Slajd 5 z 14 Wczesne i późne wiązanie WCZESNE WIĄZANIE to powiązanie wywołań funkcji z adresami określającymi, gdzie one są, już w czasie kompilacji programu. PÓŹNE WIĄZANIE to powiązanie wywołań funkcji z adresami określającymi, gdzie one są, już w czasie działania programu. Późne wiązanie ma miejsce w programach wykorzystujących funkcje wirtualne. Ale nie zawsze. Oto sytuacje gdy dla funkcji wirtualnych zachodzi wczesne wiązanie: wywołanie na rzecz obiektu (wywołanie konstruktora lub destruktora klasy podstawowej); DEFINICJA: void funkcja(klasa_podst k_podst); PRZYKŁAD WYWOŁANIA: Klasa_poch k_poch; funkcja(k_poch); jawne użycie kwalifikatora zakresu. PRZYKŁAD: wskaznik->klasa::funkcja();

Slajd 6 z 14 Funkcje przeładowane, a funkcje wirtualne FUNKCJE PRZEŁADOWANE własności: funkcje o tych samych nazwach definiowane w tym samym zakresie ważności; różnią się liczbą lub rodzajem argumentów; są wiązane w czasie kompilacji programu (wczesne wiązanie). FUNKCJE WIRTUALNE własności: funkcje o tych samych nazwach definiowane w różnych klasach; mają taką samą liczbę i rodzaj argumentów; są wiązane w czasie działania programu (późne wiązanie).

Slajd 7 z 14 Zalety i wady wirtualności funkcji składowych Zalety wirtualności funkcji składowej: możemy korzystać z dobrodziejstw późnego wiązania (wiązania podczas wywoływania funkcji w działającym programie); możemy wzbogacać funkcjonalność programu bez modyfikowania cudzego kodu. Wady wirtualności funkcji składowej: wirtualność funkcji wymaga dodatkowego miejsca w pamięci operacyjnej komputera; wybór odpowiedniej funkcji wymaga dodatkowego czasu procesora.

Slajd 8 z 14 Funkcje czysto wirtualne, a klasy abstrakcyjne KLASA ABSTRAKCYJNA to klasa, która jest tworzona tylko po to, żeby ją dziedziczyć (by była klasą podstawową dla innych klas). Można tworzyć obiekty tej klasy (ale to jakby skutek uboczny utworzenia takiej klasy). FUNKCJA CZYSTO WIRTUALNA to funkcja wirtualna bez ciała (bez żadnej treści, a nawet bez nawiasów klamrowych). PRZYKŁAD DEFINICJI: virtual void funkcja() = 0; KLASA CZYSTO ABSTRAKCYJNA to klasa wirtualna zawierająca definicję co najmniej jednej funkcji czysto wirtualnej. Nie wolno tworzyć obiektów od klas czysto abstrakcyjnych (nawet w argumentach definiowanych funkcji).

Slajd 9 z 14 Wirtualny destruktor WIRTUALNY DESTRUKTOR to inteligentnie wywoływany destruktor, który tworzy się w klasach, w których co najmniej jedna funkcja składowa jest funkcją wirtualną. W klasie zawierającej co najmniej wirtualną funkcję składową, tworzymy zawsze destruktor wirtualny. DZIAŁANIE WIRTUALNEGO DESTRUKTORA: wirtualny destruktor mając wskaźnik lub referencję do obiektu klasy podstawowej, będzie mógł ocenić, do której klasy pochodnej należy ten wskaźnik lub referencja i uruchomi destruktor właściwej klasy pochodnej (a nie destruktor klasy podstawowej, co spowodowałoby tylko częściowe zlikwidowanie obiektu). Konstruktor wirtualny nie może istnieć, ponieważ to konstruktor utworzy obiekt jakiejś klasy. Mechanizm wirtualności nie miałby co oceniać.

Slajd 10 z 14 Wirtualne funkcje składowe - ćwiczenie ĆWICZENIE 4.7.2: Omów poniższy program. Dlaczego definicja metody Wyglad w klasie Drzewo jest źle zdefiniowana? enum Pora_roku WIOSNA,LATO,JESIEN,ZIMA; class Drzewo // klasa czysto wirtualna? protected: string nazwa; public: Drzewo(string nazwa) this->nazwa = nazwa; void Wyglad(Pora_roku p) cout << nazwa << endl; // ŹLE ; class D_iglaste: public Drzewo public: D_iglaste(string nazwa): Drzewo(nazwa) ; void Wyglad(Pora_roku p); ; void D_iglaste::Wyglad(Pora_roku p) cout << nazwa << " - "; switch (p) case WIOSNA: case LATO: case JESIEN: cout << "zielone igły"; break; case ZIMA: cout << "zielone igły we śniegu"; cout << endl; class D_lisciaste: public Drzewo public: D_lisciaste(string nazwa): Drzewo(nazwa) ; void Wyglad(Pora_roku pora); ; void D_lisciaste::Wyglad(Pora_roku p) cout << nazwa << " - "; switch (p) case WIOSNA:cout << "piękne pączki"; break; case LATO: cout << "zielone liście"; break; case JESIEN: cout << "kolorowe liście"; break; case ZIMA: cout<< "bez liści we śniegu"; cout << endl; void wyswietl_drzewa(pora_roku pora, Drzewo &d1, Drzewo &d2) cout << endl << "Jest "; switch (pora) case WIOSNA: cout << "wiosna..."; break; case LATO: cout << "lato..."; break; case JESIEN: cout << "jesień..."; break; case ZIMA: cout << "zima..."; cout << endl; d1.wyglad(pora); d2.wyglad(pora); int main() D_lisciaste d1("buk"); D_iglaste d2("sosna"); wyswietl_drzewa(wiosna, d1, d2); return 0;

Slajd 11 z 14 Rzutowanie dynamic_cast TEORETYCZNY PRZYKŁAD RZUTOWANIA dynamic_cast : Konwersja obiektu klasy Rower na obiekt klasy Pojazd jest naturalna i kompilator języka C++ pozwala na to. Ale czy można zrobić odwrotnie? Nie zawsze. Nie każdy obiekt klasy Pojazd jest obiektem klasy Rower (niektóre z nich to np. samochody). Kompilator nie pozwoli na taką konwersję, chyba, że zapewnimy go o tym, że robimy to celowo i wiemy, co robimy. Dodatkowo, klasa pochodna musi dziedziczyć po klasie wirtualnej (typ polimorficzny). RZUTOWANIE dynamic_cast - to rzutowanie przeznaczone dla wskaźników i referencji do typów polimorficznych (takich, które mają co najmniej jedną funkcję składową wirtualną) w celu wymuszenia ryzykownej konwersji z klasy podstawowej do klasy pochodnej. Użycie rzutowania dynamic_cast to zdjęcie z kompilatora odpowiedzialności za rzutowanie i wzięcie jej na siebie. ĆWICZENIE 4.7.3: Przeanalizuj poniższy kod. class Pojazd virtual void Info() = 0; ; class Rower: public Pojazd string typ; public: Rower(string typ = "?"):typ(typ) void Info() ; int main() Rower r, &ref_r = r, *wsk_r = &r; Pojazd &ref_p = ref_r, *wsk_p = wsk_r; Rower &ref_nowy_r = dynamic_cast<rower&>(ref_p); Rower *wsk_nowy_r = dynamic_cast<rower*>(wsk_p); cout << &r << ' ' << &ref_nowy_r << ' ' << wsk_nowy_r << endl; return 0;

Slajd 12 z 14 Podsumowanie operatorów rzutowania Do rzutowania jawnego stosujemy 4 operatory rzutowania: static_cast<inny_typ>(obiekt) rzutowanie obiektu obiekt na typ inny_typ (np. liczba typu double może zostać rzutowana na typ int ); reinterpret_cast<inny_typ>(obiekt) patrz: temat: Wskaźniki ; const_cast<inny_typ>(obiekt) patrz: tematy: Wskaźniki i Klasy ; dynamic_cast<inny_typ>(obiekt) patrz: temat Dziedziczenie i polimorfizm. Dla zgodności wstecznej z językiem C umożliwia się także stosowanie starych operatorów (nie zaleca się ich używania, bo nie ułatwiają znajdowania błędów w programie): (inny_typ)obiekt tej formy nie możemy użyć, gdy chcemy użyć więcej parametrów rzutowania (gdy sami definiujemy sposób rzutowania); inny_typ(obiekt) operator przypominający wywołanie funkcji (tej formy trudno byłoby użyć, np. dla wskaźników). Z powyższymi operatorami można spotkać się w kodach programów pisanych w starym stylu. PRZYKŁAD: double d = 1.23; cout << static_cast<int>(d) << endl;// rzutowanie zalecane w C++ cout << int(d) << endl << (int)d << endl;

Slajd 13 z 14 Polimorfizm lista zadań ZADANIE 4.7.1: Uruchom program z ćwiczenia 4.7.1 dodając klasę: Hiszpan, Wloch albo Francuz. Pokaż działanie dodanej klasy. ZADANIE 4.7.2: Napisz program w oparciu o ćwiczenie 4.7.2. ZADANIE 4.7.3: Skopiuj i uruchom program z ćwiczenia 4.7.3. Sprawdź, co się stanie po usunięciu rzutowania dynamic_cast. ZADANIE 4.7.4: Utwórz klasę Osoba (mię i nazwisko, adres, pesel) oraz klasy pochodne: Pracownik (stanowisko, numer biura, pensja), Klient (lista transakcji klasa Transakcja zawiera informacje o dacie i kwocie transakcji). Wypełnij obiekty przykładowymi danymi i wyświetl te dane, m. in. sumę kwot transakcji. ZADANIE 4.7.5: Utwórz klasę Trojkat oraz klasy pochodne: Trojkat_prostokatny, Trojkat_rownoramienny, Trojkat_rownoboczny. W klasie bazowej należy wymusić na klasach pochodnych zdefiniowanie metody: sprawdz_poprawnosc_trójkąta. Klasy pochodne pozwalają na przechowywanie jedynie trójkątów zgodnych z nazwą na podstawie wczytanych współrzędnych wierzchołków. Klasy mają umożliwiać wyświetlanie: współrzędnych trójątów, długości boków, miary kątów, pole i obwód trójkąta.

Slajd 14 z 14 C++ - [4-7] Polimorfizm Dziękuję za uwagę ŹRÓDŁA WIEDZY: Jerzy Grębosz Symfonia C++ Standard oraz http://cplusplus.com.