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

Podobne dokumenty
Wykład 9: Polimorfizm i klasy wirtualne

TEMAT : KLASY POLIMORFIZM

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

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

PARADYGMATY PROGRAMOWANIA Wykład 4

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

Jak napisać listę jednokierunkową?

C++ - [4-7] Polimorfizm

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

Dziedziczenie. Tomasz Borzyszkowski

dr inż. Jarosław Forenc

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

Wyjątki (exceptions)

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

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

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

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

Listy powiązane zorientowane obiektowo

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

Mechanizm dziedziczenia

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

Wstęp do Programowania 2

Programowanie obiektowe

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

Programowanie obiektowe

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

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

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

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.

Wstęp do programowania obiektowego, wykład 7

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

Wykład 5: Klasy cz. 3

Wykład 8: klasy cz. 4

Podstawy informatyki. Elektrotechnika I rok. Język C++ Operacje na danych - wskaźniki Instrukcja do ćwiczenia

Programowanie obiektowe

Podstawy Programowania Obiektowego

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

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

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

Obsługa wyjątków. Język C++ WW12

Globalne / Lokalne. Wykład 15. Podstawy programowania (język C) Zmienne globalne / lokalne (1) Zmienne globalne / lokalne (2)

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Wykład 4: Klasy i Metody

Wstęp do programowania

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

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

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

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

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Laboratorium 1 - Programowanie proceduralne i obiektowe

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

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

Przekazywanie argumentów wskaźniki

Programowanie - wykład 4

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

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

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

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Wstęp do programowania

Projektowanie obiektowe. Roman Simiński Polimorfizm

Programowanie obiektowe

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

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

Programowanie obiektowe W3

Wykład 9: Metody wirtualne i polimorfizm

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Rozdział 4 KLASY, OBIEKTY, METODY

Klasy abstrakcyjne i interfejsy

Dziedziczenie jednobazowe, poliformizm

Szablony funkcji i klas (templates)

Zwracanie obiektu. Funkcja może zwracać obiekty: #include"stdafx.h #include <iostream> using namespace std; class samp { inti; public:

Mechanizm dziedziczenia

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

Programowanie obiektowe w języku

Zaawansowane programowanie w C++ (PCP)

Polimorfizm w pigułce

Programowanie Obiektowo Zorientowane w języku c++ Przestrzenie nazw

Część 4 życie programu

TEMAT : KLASY DZIEDZICZENIE

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

I - Microsoft Visual Studio C++

Wstęp do informatyki- wykład 11 Funkcje

Język C++ Programowanie obiektowe

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

1 Wskaźniki. 1.1 Główne zastosowania wskaźników

Szablony funkcji i szablony klas

Polimorfizm, metody wirtualne i klasy abstrakcyjne

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

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

1. Pierwszy program. Kompilator ignoruje komentarze; zadaniem komentarza jest bowiem wyjaśnienie programu człowiekowi.

Podstawy programowania skrót z wykładów:

Programowanie obiektowe w C++ Wykład 12

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Wykład 1: Wskaźniki i zmienne dynamiczne

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

Zaawansowane programowanie w języku C++ Programowanie obiektowe

Zadanie 2: Arytmetyka symboli

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Transkrypt:

Polimorfizm jest filarem programowania obiektowego, nie tylko jeżeli chodzi o język C++. Daje on programiście dużą elastyczność podczas pisania programu. Polimorfizm jest ściśle związany z metodami wirtualnymi. Złe operowanie mechanizmem polimorfizmu może znacznie spowolnić działanie aplikacji i doprowadzić do poważnych błędów. Czym jest polimorfizm? Polimorfizm (wielopostaciowość) jest to cecha programowania obiektowego, umożliwiająca różne zachowanie tych samych metod wirtualnych (funkcji wirtualnych) w czasie wykonywania programu. Polimorfizm jest słowem zaczerpniętym do informatyki stosunkowo niedawno, podczas rozwoju języków programowania. W języku C++ możemy korzystać z tego mechanizmu za pomocą metod wirtualnych. Dzięki niemu mamy pełną kontrolę nad wykonywanym programem, nie tylko w momencie kompilacji (wiązanie statyczne) ale także podczas działania programu (wiązanie dynamiczne) niezależnie od różnych wyborów użytkownika. Ponieważ C++ jest językiem hybrydowym, nie mamy konieczności korzystania z polimorfizmu. Zostanie on automatycznie włączony podczas zadeklarowania przynajmniej jednej metody wirtualnej w danej klasie. Metody wirtualne W internecie często używana jest nazwa funkcji wirtualnej, jednak jest ona dość mylna i nie do końca zgodna z konwencją programowania obiektowego. Funkcja wirtualna musi być funkcją składową danej klasy, a więc generalnie jest metodą. Zwykłej funkcji nie da się zadeklarować jako wirtualna. Krótkie przypomnienie Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej. Typem statycznym obiektu wskazywanego przez wskaźnik jest typ tego wskaźnika. Typem dynamicznym obiektu wskazywanego przez wskaźnik jest typ na jaki dany wskaźnik wskazuje. Dwa powyższe fakty dobrze zobrazuje ten kod: p-programowanie.pl

0 0 class Bazowa int a; class Pochodna : public Bazowa int b; // typ statyczny: Bazowa // typ dynamiczny: Pochodna Bazowa *bazowa = new Pochodna(); // typ statyczny: Pochodna // typ dynamiczny: Pochodna Pochodna *pochodna = new Pochodna(); Dzięki tym informacjom możemy napisać zwięzłą definicję metody wirtualnej: Metoda wirtualna jest to funkcja składowa klasy poprzedzona słowem kluczowym virtual, której sposób wywołania zależy od typu dynamicznego wskaźnika, a nie od typu statycznego. Definicja wydaje się trudna do zrozumienia, ale schemat jest bardzo prosty. Zobaczymy jak wygląda mechanizm przesłaniania funkcji podczas dziedziczenia, bez użycia metod wirtualnych i polimorfizmu. Aby funkcje zostały przesłonięte muszą mieć taką samą nazwę, argumenty oraz typ zwracany: p-programowanie.pl

0 0 class Bazowa void fun() cout << "Bazowa \n"; class Pochodna : public Bazowa void fun() cout << "Pochodna \n"; Bazowa *bazowa = new Pochodna(); Pochodna *pochodna = new Pochodna(); bazowa->fun(); //wyswietli: bazowa pochodna->fun();//wyswietli: pochodna bazowa = new Bazowa(); bazowa->fun(); //wyswietli: bazowa Sytuacja nas nie zaskakuje. To, która metoda zostanie wywołana zależy od typu wskaźnika na obiekt. Jest to wspomniane wcześniej wiązanie statyczne. Kompilator już podczas kompilacji programu wie, jakiego typu statycznego są obiekty i jakie metody mają zostać wywołane. Dzięki dodaniu do naszego kodu metod wirtualnych, uruchomimy mechanizm polimorfizmu. Wczesne wiązanie statyczne nie będzie miało wtedy żadnego znaczenia, ponieważ to która funkcja zostanie wywołana będzie zależało od późnego wiązania dynamicznego. p-programowanie.pl

0 0 class Bazowa virtual void fun() cout << "Bazowa \n"; class Pochodna : public Bazowa void fun() cout << "Pochodna \n"; Bazowa *bazowa = new Pochodna(); Pochodna *pochodna = new Pochodna(); bazowa->fun(); //wyswietli: pochodna pochodna->fun();//wyswietli: pochodna Słowo kluczowe virtual dobrze spełniło swoje zadanie. Widzimy jak wywołania metod są zależne od typu dynamicznego. Słowo virtual wystarczy dodać jedynie w klasie bazowej, nie ma konieczności powtarzania go w klasach pochodnych. Zastanawiasz się pewnie, do czego potrzebny jest polimorfizm oraz metody wirtualne? Bez używania polimorfizmu, programista musiał już na etapie pisania programu, wiedzieć jak będzie się on zachowywał. To za sprawą wczesnego wiązania, które musi być dostarczone kompilatorowi w momencie kompilacji i linkowania. W przypadku użycia polimorfizmu dostajemy nieograniczone możliwości projektowania aplikacji, gdzie zachowanie programu może się ciągle zmieniać. Przykład zastosowania polimorfizmu Oto prosty przykład zastosowania polimorfizmu: Posiadamy klasę bazową Pojazd oraz trzy klasy pochodne: Samochod, Rower i Rolki. Wszystkie klasy mają zdefiniowaną prostą metodę zatrzymaj() odpowiedzialną za zatrzymanie pojazdu danego typu. Deklarujemy tablicę wskaźników na obiekty klasy Pojazd (możemy ponieważ jest to klasa bazowa dla wszystkich innych klas). Dla przejrzystości kodu utworzyłem tylko obiekty klas pochodnych i zapisałem wskaźniki na obiekty do poszczególnych indeksów tablicy. Dzięki użyciu polimorfizmu możemy zatrzymać wszystkie pojazdy w jednej pętli. p-programowanie.pl

0 0 0 0 #include <iostream> #include <cstdlib> using namespace std; class Pojazd virtual void zatrzymaj() cout << "zatrzymuje pojazd..?\n"; class Samochod : public Pojazd void zatrzymaj() cout << "zatrzymuje samochod, puszczam gaz\n"; class Rower : public Pojazd void zatrzymaj() cout << "zatrzymuje rower, przestaje pedalowac\n"; class Rolki : public Pojazd void zatrzymaj() cout << "zatrzymuje rolki, przestaje ruszac nogami\n\n"; Pojazd **tablica = new Pojazd*[]; tablica[0] = new Samochod(); tablica[] = new Rower(); tablica[] = new Rolki(); for (int i = 0; i<; i++) tablica[i]->zatrzymaj(); p-programowanie.pl

Tak jak pisałem wcześniej, o wywołaniu odpowiedniej przesłoniętej metody zadecydowało późne wiązanie. Uzyskaliśmy ten efekt dzięki zadeklarowaniu funkcji wirtualnej w klasie bazowej. A więc zadziałał polimorfizm. Gdybyśmy usunęli słowo virtual, trzy razy zostałaby wywołana funkcja klasy bazowej zostałby trzy razy wyświetlony napis: zatrzymuje pojazd..?. Przykład jest dość trywialny ale w chwili obecnej wydawał mi się najprostszy do ukazania zalet polimorfizmu a przede wszystkim jego praktycznej implementacji. Oczywiście wyobraź sobie sytuację, że w programie istnieje kilkaset obiektów a nie tylko trzy. Wtedy wygoda jaką zyskaliśmy jest nieoceniona. Nie należy przesadzać Polimorfizm kosztuje. Działa to w ten sam sposób jak deklaracja zmiennych statycznych i dynamicznych (stos jest szybszy od sterty). Gdy używamy polimorfizmu program aż do czasu uruchomienia nie wie jak będzie działał, ponieważ obiekt na jaki wskazuje wskaźnik może zmienić się 0 razy w ciągu minuty, zależnie od działania użytkownika. 0 0 0 #include <iostream> #include <cstdlib> using namespace std; class Klasa int a,b,c; virtual void fun() cout << "test"; class Klasa int a,b,c; void fun() cout << "test"; Klasa *klasa = new Klasa; Klasa *klasa = new Klasa; cout << sizeof(*klasa) << "\n"; //wyswietli cout << sizeof(*klasa) << "\n"; //wyswietli p-programowanie.pl

Klasy polimorficzne zajmują więcej miejsca w pamięci, ponieważ kompilator automatycznie dodaje do nich wskaźnik vptr wskazujący na tablicę vtab. Dla każdej klasy musi istnieć osobny wskaźnik i osobna tablica. Tablica jest generowana automatycznie i zawiera wskaźniki do funkcji, wygenerowane przez kompilator. Nie wiem na jakiej zasadzie odbywa się generowanie zawartości tablicy i nie umiem nic więcej na ten temat napisać. Sama tablica w budowie nie przypomina niczego nadzwyczajnego. Jej podgląd umożliwia m.in. środowisko Visual Studio po dopisaniu do kompilatora odpowiednich parametrów (zostanie wtedy wygenerowana automatycznie w formie pliku tekstowego). Traktuj ten artykuł jako wstęp, opisałem w nim związek pomiędzy metodami wirtualnymi a polimorfizmem. Jeżeli temat dalej Cię interesuje, zapraszam do bardziej szczegółowego wpisu przedstawiającego Polimorfizm w C#. p-programowanie.pl