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



Podobne dokumenty
Programowanie 2. Język C++. Wykład Relacje między klasami, klasy zagnieŝdŝone, klasy lokalne

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

Programowanie obiektowe w języku

Dziedziczenie jednobazowe, poliformizm

Dziedziczenie. Ogólna postać dziedziczenia klas:

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

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

Zaawansowane programowanie w języku C++ Programowanie obiektowe

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

Zaawansowane programowanie w C++ (PCP)

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.

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

PARADYGMATY PROGRAMOWANIA Wykład 4

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

Wstęp do programowania obiektowego, wykład 7

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

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

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

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

Plik klasy. h deklaracje klas

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

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

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

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

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

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

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

TEMAT : KLASY DZIEDZICZENIE

Wykład 9: Polimorfizm i klasy wirtualne

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

hierarchie klas i wielodziedziczenie

Programowanie obiektowe w C++ Wykład 12

dr inż. Jarosław Forenc

Do czego służą klasy?

Programowanie, część I

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

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

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

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

TEMAT : KLASY POLIMORFIZM

Klasy abstrakcyjne i interfejsy

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

Wstęp do Programowania 2

PARADYGMATY PROGRAMOWANIA Wykład 2

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

C++ - [4-7] Polimorfizm

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

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

Wprowadzenie do programowanie obiektowego w języku C++

Podstawy Programowania Obiektowego

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

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

referencje Wykład 2. Programowanie (język C++) Referencje (1) int Num = 50; zdefiniowano zmienną Num (typu int) nadając jej wartość początkową 50.

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

Szablony klas, zastosowanie szablonów w programach

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

Mechanizm dziedziczenia

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

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

KLASY cz.1. Dorota Pylak

Techniki Programowania wskaźniki 2

Kurs WWW. Paweł Rajba.

Materiały do zajęć VII

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

Do czego służą klasy?

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.

Zaawansowane programowanie w C++ (PCP)

Programowanie obiektowe

Programowanie Obiektowe i C++

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

Polimorfizm, metody wirtualne i klasy abstrakcyjne

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

Wykład 8: klasy cz. 4

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

Programowanie Obiektowe i C++

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

Język JAVA podstawy. Wykład 4, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

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

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY

Kompozycja i dziedziczenie klas

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

.NET Klasy, obiekty. ciąg dalszy

Dziedziczenie. Tomasz Borzyszkowski

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

Język C++ Różnice między C a C++

Dziedziczenie. dr Jarosław Skaruz

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

Informatyka 2. Wykład nr 3 ( ) Politechnika Białostocka. - Wydział Elektryczny. dr inŝ. Jarosław Forenc

Abstrakcyjny typ danych

Listy powiązane zorientowane obiektowo

Podstawy Programowania Obiektowego

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

Programowanie, część I

Wykład 5 Okna MDI i SDI, dziedziczenie

Projektowanie obiektowe. Roman Simiński Polimorfizm

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

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Programowanie obiektowe w C++ Wykªad 4

Transkrypt:

9.1 Ukrywanie metod, metody nadpisane... 1 9.2 Metody wirtualne, wirtualny destruktor... 2 9.3 Metody czysto wirtualne... 6 9.4 Klasy abstrakcyjne... 7 9.5 Wielodziedziczenie... 9 9.1 Ukrywanie metod, metody nadpisane Metoda z klasy bazowej jest zasłonięta przez metodę z klasy pochodnej. To znaczy, Ŝe obiekty klasy pochodnej nie mają dostępu do ukrytych metod z klasy bazowej. Nadpisanie metody (method overriding) z klasy bazowej oznacza zdefiniowanie w klasie pochodnej metody o takiej samej sygnaturze. Zwracany typ metody nadpisanej moŝe być taki, jak metody nadpisanej lub kowariantny z klasą bazową. Przykład 1. Metoda z klasy B zasłania obiektom typu B metodę z klasy A (w09-01-ukrywaniemetod.cpp). A(){cout << "A()" << endl; virtual ~A(){cout << "~A()" << endl; void metoda() const { cout << "metoda() w A" << endl; class B : public A { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; void metoda() const { cout << "metoda() w B" << endl; A a; B b; a.metoda(); b.metoda(); // metoda() z klasy A // metoda() z klasy B // obiekt b nie ma dostępu do metoda() z A // metoda() z A jest zasłonięta przez metoda() z B b.a::metoda(); // metoda() z klasy A A * p = new B; p->metoda(); // metoda() z klasy A 1

9.2 Metody wirtualne, wirtualny destruktor Definicja metody wirtualnej: virtual <zwracanytyp> nazwafunkcji(<typarg1> <nazwaarg1>, ){ <instrukcje>; Metoda wirtualna jest zdefiniowana i zaimplementowana w klasie bazowej. W klasie pochodnej jest ponownie zaimplementowana. Uwaga: metody wirtualne nie wymuszają implementacji w klasie pochodnej, poniewaŝ mają domyślną implementację w klasie bazowej. Klasa która zawiera metodę wirtualną nazywa się klasą polimorficzną. Metody statyczne nie mogą być deklarowane jako wirtualne. Nie moŝna definiować funkcji wirtualnych, tzn. funkcja musi naleŝeć do jakieś klasy aby być wirtualną. Jak kompilator odnajduje wirtualne metody w klasach? Kompilator tworzy tablicę, zwaną VTABLE, do której zapisuje adresy wirtualnych metod danej klasy. KaŜda klasa zawierająca wirtualną metodę posiada wskaźnik (vpointer) który wskazuje instancji klasy na adres tablicy VTABLE (zawierającą adresy wirtualnych metod). Przykład 1. Metody wirtualne (w09-02-metodywirtualne.cpp). virtual void metoda() const { cout << "metoda() w A" << endl; // void metoda() const { cout << "metoda() w A" << endl; class B : public A { void metoda() const { cout << "metoda() w B" << endl; void funk(a& a) { a.metoda(); B b; A *pa; pa= &b; pa->metoda(); // metoda() z B b.metoda(); A a; pa= &a; pa->metoda(); // metoda() z A a.metoda(); funk(b); // metoda() w B // gdy metoda() w A nie jest wirtualna, to // funk(b); // metoda() w A 2

W przypadku definiowania obiektów na stercie za pomocą upcast, naleŝy zadeklarować wirtualnego destruktora. Przykład 2. Definiowanie obiektów upcast. class B : public A { A *p= new B; // upcast // Przykład 3. Wywołanie wirtualnego destruktora przy usuwaniu obiektu ze sterty (w09-03-wirtualnydestruktor.cpp). #include<iostream> A(){ cout << "A()" << endl; virtual ~A(){ cout << "~A()" << endl; // ~A(){cout << "~A()" << endl; class B :public A { B(){ cout << "B()" << endl; ~B(){ cout << "~B()" << endl; A *p = new B; // upcast //---------------------------------------------------+ // Wynik działania programu ze zwykłym destruktorem /* A() B() ~A() // brak destruktora ~B() */ //---------------------------------------------------+ //---------------------------------------------------+ // Wynik działania programu z wirtualnym destruktorem /* A() B() ~B() ~A() */ //---------------------------------------------------+ 3

Przykład 4. Metody wirtualne, wirtualny destruktor, tworzenie obiektów na stercie upcast (w09-04-metodywirtualne.cpp). A(){cout << "A()" << endl; virtual ~A(){cout << "~A()" << endl; void metoda1() const { cout << "metoda1() w A" << endl; virtual void metoda2() const { cout << "metoda2() w A" << endl; class B : public A { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; void metoda1() const { cout << "metoda1() w B" << endl; void metoda2() const { cout << "metoda2() w B" << endl; A *p = new B; p->metoda1(); p->metoda2(); // upcast // wywołana jest metoda() z klasy A // wywołana jest metoda() z klasy B p->a::metoda2(); // wywołana jest metoda() z klasy A 4

Deklaracja metody wirtualnej nie musi zawierać specyfikatora virtual. Metoda zdefiniowana jako wirtualna w klasie bazowej, nadpisana w klasie pochodnej jest teŝ wirtualna. Przykład 5. (w09-05-metodywirtualnebezvirtual.cpp) A(){cout << "A()" << endl; virtual ~A(){cout << "~A()" << endl; virtual void metoda() const { cout << "metoda() w A" << endl; //void metoda() const { cout << "metoda() w A" << endl; class B : public A { B(){cout << "B()" << endl; virtual ~B(){cout << "~B()" << endl; // metoda() jest wirtulna void metoda() const { cout << "metoda() w B" << endl; class C : public B { C(){cout << "C()" << endl; ~C(){cout << "~C()" << endl; void metoda() const { cout << "metoda() w C" << endl; A *p = new B; p->metoda(); // wywołana jest metoda() z klasy B p->a::metoda(); B *pp = new C; pp->metoda(); // wywołana jest metoda() z klasy C pp->b::metoda(); A *ppp = new C; ppp->metoda(); // wywołana jest metoda() z klasy C delete pp; delete ppp; 5

Przykład 6. Metoda fun(int) z klasy B zasłania metodę z fun() klasy A (w09-06-metodywirtualne-f(int).cpp). A(){cout << "A()" << endl; virtual ~A(){cout << "~A()" << endl; virtual void metoda() const { cout << "metoda() w A" << endl; virtual void fun() const { cout << "fun() w A" << endl; class B : public A { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; void metoda() const { cout << "metoda() w B" << endl; void fun(int x) const { cout << "fun(int) w B, x = " << x << endl; B b; // b.fun(); // błąd, fun(int) z B zasłania fun() z A b.fun(30); A *p = new B; p->metoda(); p->a::metoda(); // wywołana jest metoda() z klasy B // wywołana jest metoda() z A p->fun(); // wywołana jest fun() z klasy A // p->fun(10); // błąd, nie moŝna wywołać fun(int) z B // p->b::fun(20); // błąd, nie moŝna wywołać fun(int) z B 9.3 Metody czysto wirtualne Definicja metody czysto wirtualnej: virtual <zwracanytyp> nazwafunkcji(<typarg1> <nazwaarg1>, ) = 0; Przykład 1. Definicja metody czysto wirtualnej. class Abstrakcyjna { virtual void metoda() const = 0; 6

9.4 Klasy abstrakcyjne Klasa jest abstrakcyjna jeŝeli zawiera lub dziedziczy przynajmniej jedną metodę czysto wirtualną. Klasa abstrakcyjna nie moŝe być dziedziczona, tzn. moŝe być tylko klasą od której się dziedziczy. Nie moŝna utworzyć instancji (obiektu) klasy abstrakcyjnej. MoŜna definiować obiekty typy referencyjnego lub wskaźniki klasy abstrakcyjnej. Uwaga: deklaracja metody czysto wirtualnej, definiowanie klasy abstrakcyjnej, wymusza w klasie pochodnej implementację metody czysto wirtualnej. Przykład 1. Definicja klasy abstrakcyjna (w09-07-klasaabstrakcyjna.cpp) class Abs{ Abs(){cout << "Abs()" << endl; virtual ~Abs(){cout << "~Abs()" << endl; virtual void funkcja() const = 0; void func() { cout << "func() w Abs" << endl; // implementacja metody czysto wirtualnej w klasie abstrakcyjnej // implementacja nie inline void Abs::funkcja() const { cout << "funkcja() w Abs" << endl; class B : public Abs { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; // funkcja czysto wirtualna musi być implemtowana w klasie B // jeŝeli nie, to klasa B będze rownieŝ abstrakcyjna void funkcja() const { cout << "funkcja() w B " << endl; void func() { cout << "func() w B" << endl; void main( ) { // Abs a; // błąd, nie moŝna utworzyć instancji klasy abstakcyjnej B b; b.func(); // func() z klasy B b.funkcja(); // funkcja() z klasy B Abs * p = new B; p->func(); // func() z klasy Abs 7

Brak implementacji metody czysto wirtualnej w klasie pochodnej powoduje, Ŝe klasa pochodna jest klasą abstrakcyjną Przykład 2. Brak implementacji w klasie B metody() z klasy Abs powoduje, Ŝe B jest klasą abstrakcyjną (w09-08-klasyabstrakcyjne.cpp) class Abs { Abs(){cout << "Abs()" << endl; ~Abs(){cout << "~Abs()" << endl; virtual void metoda() = 0; // metoda czysto wirtualna class A : virtual public Abs { A(){cout << "A()" << endl; ~A(){cout << "~A()" << endl; private: void metoda(){ // implementacja metody czysto wirtualnej class B : virtual public Abs { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; // brak implementacji metody czysto wirtualnej class C : public A, public B { C(){cout << "C()" << endl; ~C(){cout << "~C()" << endl; private: void metoda(){ // implementacja metody czysto wirtualnej void main() { A a; // B b; // B jest klasą abstrakcyjną C c; 8

9.5 Wielodziedziczenie Przykład 1. Wielodziedziczenie typu public. class B { class C : public A, public B { Przykład 2. Klasy A i B są bazowa dla klasy C (w09-09-wielodziedziczenie.cpp). A(){ cout << "A()" << endl; ~A(){ cout << "~A()" << endl; class B { B(){ cout << "B()" << endl; ~B(){cout << "~B()" << endl; class C : public A, public B { C(){ cout << "C()" << endl; ~C(){cout << "~C()" << endl; C c; //-------------------------------------------+ // Wynik działania programu /* A() B() C() ~C() ~B() ~A() */ //-------------------------------------------+ 9

Przykład 3. Wielodziedziczenie biblioteka iostream. 10

Przykład 4. Wirtualne dziedziczenie (w09-10-wirtualnedziedziczenie.cpp). A(){cout << "A()" << endl; ~A(){cout << "~A()" << endl; // class B : public A { class B : virtual public A { B(){cout << "B()" << endl; ~B(){cout << "~B()" << endl; // class C : public A { class C : virtual public A { C(){cout << "C()" << endl; ~C(){cout << "~C()" << endl; class D : public B, public C { D(){ cout << "D()" << endl; ~D(){ cout << "~D()" << endl; void main() { D d; 11

//-----------------------------------------------------+ // Wynik działania programu z wirtualnym dziedziczeniem /* A() B() C() D() ~D() ~C() ~B() ~A() */ //-----------------------------------------------------+ //-----------------------------------------------------+ // Wynik działania programu ze zwykłym dziedziczeniem /* A() B() A() C() D() ~D() ~C() ~A() ~B() ~A() */ //-----------------------------------------------------+ 12