PARADYGMATY PROGRAMOWANIA Wykład 4

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

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

PARADYGMATY PROGRAMOWANIA Wykład 3

Programowanie obiektowe w języku

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Dziedziczenie jednobazowe, poliformizm

Szablony klas, zastosowanie szablonów w programach

PARADYGMATY PROGRAMOWANIA Wykład 2

Materiały do zajęć VII

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

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

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

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

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

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

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

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

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

TEMAT : KLASY DZIEDZICZENIE

Programowanie obiektowe w C++ Wykład 12

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

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

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

Zaawansowane programowanie w C++ (PCP)

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

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

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

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

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

Zaawansowane programowanie w języku C++ Klasy w C++

Kurs WWW. Paweł Rajba.

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

Wprowadzenie do programowanie obiektowego w języku C++

Język C++ Programowanie obiektowe

Polimorfizm. dr Jarosław Skaruz

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

dr inż. Jarosław Forenc

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

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

ATD. Wykład 8. Programowanie (język C++) abstrakcyjny typ danych. Abstrakcyjne typy danych (ATD) Metody czysto wirtualne. Definicje i uwagi:

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

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

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

C++ - [4-7] Polimorfizm

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

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

Dziedziczenie. Ogólna postać dziedziczenia klas:

Plik klasy. h deklaracje klas

Programowanie w Internecie. Java

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

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

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

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

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

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Mechanizm dziedziczenia

Wykład 6: Dziedziczenie

Instrukcja do pracowni specjalistycznej z przedmiotu. Obiektowe programowanie aplikacji

Programowanie Obiektowe i C++

Funkcje wirtualne. Wskaźniki do klas pochodnych są podstawą dla funkcji wirtualnych i polimorfizmu dynamicznego.

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Zaawansowane programowanie w C++ (PCP)

Wykład 8: klasy cz. 4

Wykład 9: Polimorfizm i klasy wirtualne

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

Szablony. Szablony funkcji

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

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

Lab 9 Podstawy Programowania

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

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

TEMAT : KLASY POLIMORFIZM

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

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Podstawy Programowania Obiektowego

Wykład 4: Klasy i Metody

Metody Metody, parametry, zwracanie wartości

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Dziedziczenie. Tomasz Borzyszkowski

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

Abstrakcyjny typ danych

Typy zmiennych proste i złożone. Programowanie komputerów. Tablica. Złożone typy zmiennych. Klasa. Struktura

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

EGZAMIN PROGRAMOWANIE II (10 czerwca 2010) pytania i odpowiedzi

Wstęp do programowania obiektowego, wykład 7

Podstawy programowania obiektowego

Wartości domyślne, przeciażenia funkcji

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

PROGRAMOWANIE OBIEKTOWE W C++ cz. 2. Dziedziczenie, operacje wej cia-wyj cia, przeładowanie operatorów.

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Szablony funkcji i szablony klas

Programowanie obiektowe

Wstęp do Programowania 2

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Programowanie, część I

Identyfikacje typu na etapie. wykonania (RTTI)

Transkrypt:

PARADYGMATY PROGRAMOWANIA Wykład 4 Metody wirtualne i polimorfizm Metoda wirualna - metoda używana w identyczny sposób w całej hierarchii klas. Wybór funkcji, którą należy wykonać po wywołaniu metody wirtualnej jest określony nie na etapie kompilacji, ale w momencie wykonania. Taka sytuacja jest możliwa, gdy pod wskaźnik typu klasy bazowej podstawiony jest obiekt jednej z klas pochodnych. Polimorfizm - zachowanie polegające na tym, że ta sama instrukcja kodu źródłowego wywołująca pewną metodę może w trakcie wykonywania w rzeczywistości wywoływać różne funkcje. Stosowane w celu: stworzenie kodu ogólnego i jednorodnego, używanego w jednorodny sposób dla wszystkich klas hierarchii, zwiększenie możliwości ponownego wykorzystania i dalszego rozszerzania. class Personel... void print() const; virtual float oblicz_place() = 0;... class PracAkord(): public Personel int il_godz_przepr; float stawka; virtual float oblicz_place() return il_godz_przepr * stawka;

class PracEtat(): public Personel float placa_mies; virtual float oblicz_place() return placa_mies; class TablePersonel TablePersonel( int _rozmiar ); void add( Personel *p); void print() const; float suma_wyplat() const; private: Personel **table; int rozmiar; int index; TablePersonel::TablePersonel( int _rozmiar ): rozmiar(_rozmiar), index(0) table = new Personel[rozmiar]; TablePersonel::add( Personel *p ) if ( index < rozmiar ) table[index++] = p; void TablePersonel::print() const for (int i=0; i < index; i++) table[i]->print(); float TablePersonel::suma_wyplat() const float suma;

for (int i=0; i < index; i++) float += table[i]->oblicz_place(); return( suma ); Zachowanie kompilatora związane ze statycznym zakresem wywołania funkcji: przy wykorzystaniu wskaźnika do klasy bazowej ( table[i] ) kompilator przeszukuje zbiór metod tej właśnie klasy table[i] -> oblicz_płace() - błąd bo nie ma metody oblicz_place() w klasie Personel, table[i] -> print() - wywołanie funkcji klasy bazowej, również wtedy gdy wskażnik table[i] wskazuje na obiekt klasy pochodnej. Polimorfizm zapewnia, że rzeczywisty typ obiektu na który wskazuje wskaźnik (a nie typ wskaźnika) określa wywołaną funkcję. Zamiast wywołania statycznego kompilator stosuje wywołanie dynamiczne wiążące wywołanie z konkretną funkcja w czasie wykonania. Zasady stosowania funkcji wirtualnych: Funkcje wirtualne stosujemy, gdy można przewidzieć, że w każdej z klas pochodnych zostaną one przedefiniowane. Nie ma obowiązku definiowania funkcji wirtualnej o danej nazwie w klasie pochodnej. W przypadku przetwarzania obiekt z klasy pochodnej nie redefiniującej danej metody wirtualnej zostanie wywołana metoda klasy bazowej. Mechanizm ten działa tylko w odniesieniu do odwołania do obiektu przez wskaźnik. Składnia: przed zwykłą deklaracją funkcji w klasie bazowej umieścić słowo kluczowe virtual, nie ma obowiązku umieszczania tego słowa przed odpowiadającymi funkcjami wirtualnymi w klasach pochodnych, składniowo jest to jednak dozwolone i dla przejrzystości kodu ZALECANE, prototyp funkcji wirtualnych w klasie bazowej i we wszystkich klasach pochodnych musi być taki sam. class Bazowa

virtual void f() ( printf( "f() - klasa bazowa\n") ); void g() ( printf( "g() - klasa bazowa\n"); class Pochodna1 : public Bazowa virtual void f() ( printf( "f() - klasa Pochodna1\n") ); void g() ( printf( "g() - klasa Pochodna1\n"); class Pochodna2 : public Bazowa virtual void f() ( printf( "f() - klasa Pochodna2\n") ); void g() ( printf( "g() - klasa Pochodna2\n"); void main() Bazowa b; Pochodna1 p1; Pochodna2 p2; Bazowa *p = &b; p->f(); p->g(); p = &p1; p->f(); p->g(); p = &p2; p->f(); p->g(); Uzdatnienie poprzedniego przykładu: class Personel virtual void print() const; virtual float oblicz_place() const (return 0); Destruktor wirtualny

Zaleca się dla każdej klasy bazowej posiadającej metody wirtualne zadeklarowanie również wirtualnego destruktora. - także jeśli w klasie bazowej nie wykonuje on żadnej czynności. class Bazowa virtual void f() (); // brak destruktora wirtualnego class Pochodna : public Bazowa Pochodna( int _rozmiar ); ~Pochodna(); private: int *pi; Pochodna::Pochodna( int _rozmiar) pi = new int[ _rozmiar ]; Pochodna::~Pochodna() delete [] pi; void main() Bazowa *pb; pb = new Pochodna(10); delete pb; // mylne zwolnienie obszaru pamięci korekta: class Bazowa virtual void f() (); virtual ~Bazowa*() (); Czyste funkcje wirtualne oraz klasy abstrakcyjne Nie ma obowiązku definiowania funkcji wirtualnej w klasie bazowej (jej deklaracja jest tylko podstawą dla kompilatora do zignorowania pozornego błędu). Taka metoda nazywa się czystą metodą wirtualną.

Czystą metodę wirtualną oznaczamy pisząc po jej deklaracji =0 class Personel virtual void print() const = 0; virtual float oblicz_place() const = 0; Jeśli klasa zawiera czystą metodę wirtualną to jest ona klasą abstrakcyjną. Nie można tworzyć obiektów klas wirtualnych, ale można tworzyć wskaźniki do nich.

Konwersja typów W przypadku niezgodności typów w określonym kontekście (operandy operatora, podstawienie parametrów, zwracanie wartości funkcji) gdy zgodność wymaga pojawienia się obiektu danej klasy kompilator usiłuje dokonać konwersji stosując jeden z dostępnych konstruktorów klasy. String nazwisko, inne_nazwisko;... if (nazwisko == "KAIN") inne_nazwisko = "KOWAL"; nazwisko = inne_nazwisko + "SKI"; if (nazwisko.operator== String("KAIN")) inne_nazwisko = String("KOWAL"); nazwisko = inne_nazwisko + String("SKI"); Rodzaje konwersji automatycznych wykonywanych przez kompilator: 1. konwersje typu predefiniowanego na jedną z utworzonych klas, 2. konwersje klasy na typ predefiniowany 3. konwersje pomiędzy różnymi klasami. ad. 1) konwersje typu predefiniowanego na jedną z utworzonych klas konstruktor pewnej klasy X pobierający tylko jeden argument typu T może być wykorzystany jako funkcja konwertująca typ T w typ X, np class String String( char *_stg); // konstruktor konwertujący typ char * w typ String... Reguły konwersji: 1. Najpierw sprawdzane jest czy istnieje funkcja (ewentualnie [przeciążona) lub przeciążony operator, który zaakceptuje bezpośrednio przekazane argumenty,

2. Sprawdzane jest czy można doprowadzić do zgodności typów stosując predefiniowane w C++ konwersje (np. wszelkie konwersje liczbowe int->float, float->int itd.) 3. Sprawdzana jest możliwość konwersji za pomocą funkcji zdefiniowanych w programie, przy czym sprawdzany jest tylko jeden poziom konwersji (tzn. jeśli wymagany Z a przekazany X to musi być zdefiniowane bezpośrednia konwersja X->Z, nie wystarczy łańcuch konwersji X->Y oraz Y->Z). ad. 2) konwersje klasy na typ predefiniowany Dla każdego typu T kompilator pozwala zdefiniować w klasie X funkcję skłądową operator T(), wykonującą konwersję obiektu X w obiekt typu T. class Zespolona double re, im, Zespolona( double _re); Zespolona( double _re, double _im); Zespolona( void ); // konwersja typu Zespolona na typ double operator double() return re; double a, b, c; Zespolona z1, z2; a = b + z1; // a = b + z1.double(); - KONWERSJA NIEJAWNA a = b + (double)z1 // konwersja jawna - składnia klasyczna; a = b + double(z1) // konwersja jawna - składnia funkcyjna a = b + z1.double(); // jawne wywołanie funkcji konwersji Funkcja konwersji nie przyjmuje żadnego argumentu ani nie deklaruje się zwracanej przez nią wartości. ad 3) konwersje pomiędzy różnymi klasami Można w typ przypadku stosować dowolną z metod 1. lub 2. Np. przy kowersji pomiędzy klasami Zespolona i T: class Zespolona Zespolona( T _t ); // Konwersja T -> Zespolona operator T() // Konwersja Zespolona -> T