TEMAT : KLASY DZIEDZICZENIE

Podobne dokumenty
TEMAT : KLASY POLIMORFIZM

Wykład 8: klasy cz. 4

Dziedziczenie jednobazowe, poliformizm

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

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

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

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

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

Enkapsulacja, dziedziczenie, polimorfizm

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

Do czego służą klasy?

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

Wykład 5: Klasy cz. 3

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

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

Podstawy Programowania Obiektowego

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

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

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

PARADYGMATY PROGRAMOWANIA Wykład 2

Wprowadzenie do programowanie obiektowego w języku C++

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

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

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

Dziedziczenie. Ogólna postać dziedziczenia klas:

PARADYGMATY PROGRAMOWANIA Wykład 4

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

class Student Deklaracja klasy Osoba: Deklaracja klasy Student:

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

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.

dr inż. Jarosław Forenc

Mechanizm dziedziczenia

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

Język C++ umożliwia przeciążanie operatora, tzn. zmianę jego znaczenia na potrzeby danej klasy. W tym celu definiujemy funkcję o nazwie:

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

Aplikacje w środowisku Java

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

Polimorfizm. dr Jarosław Skaruz

Programowanie komputerowe. Zajęcia 7

Programowanie obiektowe

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

Do czego służą klasy?

Język C++ zajęcia nr 2

Abstrakcyjny typ danych

Dziedziczenie. Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut.

Programowanie obiektowe

KLASY cz.1. Dorota Pylak

Dziedziczenie. dr Jarosław Skaruz

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

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

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Klasy abstrakcyjne i interfejsy

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.

Wykład 5 Okna MDI i SDI, dziedziczenie

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Zaawansowane programowanie w C++ (PCP)

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

Materiały do zajęć VII

Programowanie, część I

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

Rozdział 4 KLASY, OBIEKTY, METODY

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

Podstawy algorytmiki i programowania - wykład 4 C-struktury

PARADYGMATY PROGRAMOWANIA Wykład 3

Programowanie obiektowe i zdarzeniowe

C++ - [4-7] Polimorfizm

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

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.

Konstruktor kopiujacy

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

Technologie i usługi internetowe cz. 2

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

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

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

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

Mechanizm dziedziczenia

Zaawansowane programowanie w języku C++ Programowanie obiektowe

Programowanie Obiektowo Zorientowane w języku C++ Klasy, pola, metody

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

Programowanie obiektowe w C++ Wykład 12

Pola i metody statyczne. Klasy zawierające pola i metody statyczne

Kurs WWW. Paweł Rajba.

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

Definiowanie własnych klas

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

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

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

Programowanie Obiektowe i C++

Programowanie obiektowe

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

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

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

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

Szablony funkcji i szablony klas

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

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

Wykład 4: Klasy i Metody

Szablony klas, zastosowanie szablonów w programach

Transkrypt:

TEMAT : KLASY DZIEDZICZENIE Wprowadzenie do dziedziczenia w języku C++ Język C++ możliwa tworzenie nowej klasy (nazywanej klasą pochodną) w oparciu o pewną wcześniej zdefiniowaną klasę (nazywaną klasą podstawową). Klasa pochodna dziedziczy dane oraz funkcje składowe z klasy podstawowej. W ten sposób nie musimy tworzyć całego kodu klasy pochodnej a jedynie nowe jej elementy, które nie były do tej pory zaimplementowane w klasie podstawowej. Oczywiście klasa pochodna może stać się klasą podstawową dla kolejnej tworzonej przez nas klasy. W programowaniu obiektowym rozróżniamy następujące rodzaje dziedziczenia: dziedziczenie jednokrotne (pojedyncze) gdy klasa pochodna tworzona jest na podstawie tylko jednej klasy podstawowej (oczywiście klasa bazowa może dziedziczyć również z jakiejś innej klasy), dziedziczenie wielokrotne gdy klasa pochodna tworzona jest na podstawie wielu klas podstawowych. Zadanie 1 Przeanalizuj sposób implementacji przedstawionych poniżej dwóch klas CPunkt oraz CKolo. Jak mogłaby wyglądać definicja klasy CPunkt, gdyby programista nie zaplanował wykorzystania mechanizmu dziedziczenia danych i funkcji składowych klasy CPunkt przez klasę CKolo? Implementacja klasy CPunkt jako klasy podstawowej class CPunkt friend ostream & operator << (ostream &, const CPunkt &); public: CPunkt(double x = 0.0, double y = 0.0); ~CPunkt(); void SetPunkt (double x_t, double y_t); double GetX () const return x;; double GetY () const return y;; void Drukuj () const; protected: double x,y; ; CPunkt::CPunkt(double x_t, double y_t) SetPunkt(x_t,y_t); CPunkt::~CPunkt() void CPunkt::SetPunkt (double x_t, double y_t) x = x_t; y = y_t; void CPunkt::Drukuj () const cout << "[" << x << ", " << y << "]"; ostream & operator << (ostream & output, const CPunkt & pkt) output << "[" << pkt.x << ", " << pkt.y << "]"; return output; 1

Implementacja klasy CKolo dziedziczącej z klasy CPunkt class CKolo : public CPunkt friend ostream & operator << (ostream &, const CKolo &); public: CKolo(double R = 0.0, double x = 0.0, double y = 0.0); ~CKolo(); void SetR (double R_t); double GetR () const; double ObliczObszar () const; protected: double R; ; CKolo::CKolo(double R_t, double x_t, double y_t) : CPunkt(x_t,y_t) SetR(R_t); CKolo::~CKolo() void CKolo::SetR (double R_t) if (R_t >= 0.0) R = R_t; else R = 0.0; double CKolo::GetR () const return R; double CKolo::ObliczObszar () const return 3.14159*R*R; ostream & operator << (ostream & output, const CKolo & kolo) output << "Srodek kola = " << CPunkt(kolo) << ", R = " << kolo.r; return output; Analiza istotnych elementów klas CPunkt oraz CKolo z punktu widzenia mechanizmu dziedziczenia W powyższym przykładzie widzimy propozycję dwóch klas. Pierwsza z nich, tj. klasa CPunkt, jest klasą podstawową dla klasy pochodnej CKolo. Zadaniem klasy CPunkt jest reprezentowanie w programie abstrakcyjnego obiektu punktu, o którym zakładamy, że definiują go jego współrzędne x i y. Klasa CKolo reprezentuje natomiast abstrakcyjny obiekt koła, które jest zdefiniowane przez współrzędne środka tego koła oraz długość jego promienia. Do ważnych elementów wykorzystywanych w powyższych klasach możemy zaliczyć: wybór sposobu dziedziczenia przez klasę CKolo class CKolo : public CPunkt Standard języka C++ przewiduje trzy rodzaje dziedziczenia: publiczne, chronione i prywatne. W rozważanym przykładzie klasa CKolo dziedziczy z klasy CPunkt wykorzystując do tego zadania interfejs publiczny. Dziedziczenie oznaczone jest dwukropkiem w nagłówku definicji klasy. Słowo kluczowe public określa rodzaj dziedziczenia, tj. dziedziczenie publiczne. Dalej w kolejności podajemy nazwę klasy podstawowej dla definiowanej właśnie klasy pochodnej. Dziedziczenie publiczne zakłada, że dane i funkcje składowe klasy podstawowej zadeklarowane jako public i private, stają się automatycznie danymi i funkcjami składowymi odpowiednio publicznymi i prywatnymi klasy pochodnej. Należy jednak mieć na 2

uwadze fakt, że prywatne składowe klasy podstawowej nie są bezpośrednio dostępne dla klas pochodnych. Klasa pochodna ma do nich dostęp za pośrednictwem publicznych funkcji dostępowych zdefiniowanych w klasie podstawowej. sposób określania dostępu do danych klasy podstawowej CPunkt protected: double x,y; Zadeklarowanie składowych x, y przy użyciu specyfikatora dostępu protected uniemożliwia bezpośredni dostęp do nich dla klientów klasy CPunkt w programie. Dostęp do danych mają funkcje składowe klasy oraz funkcje nią zaprzyjaźnione, natomiast bezpośredni dostęp do tych danych z programu jest możliwy wyłącznie poprzez odpowiednie publiczne funkcje dostępowe. W przypadku, gdy chcemy zastosować mechanizm dziedziczenia, w definicji klasy podstawowej najczęściej wykorzystujemy tryb dostępu protected. W ten sposób dostęp do danych mają funkcje składowe i funkcje zaprzyjaźnione zdefiniowane zarówno w klasie podstawowej jak i w klasie pochodnej. Wszystkie składowe publiczne i chronione klasy CPunkt są dziedziczone jako odpowiednio, składowe publiczne i chronione w klasie CKolo. Oznacza to, ze interfejs publiczny klasy CKolo zawiera zarówno publiczne składowe klasy CPunkt, jak i publiczne składowe klasy CKolo. sposób implementacji konstruktora klasy pochodnej CKolo / wywoływanie konstruktora klasy podstawowej przez konstruktor klasy pochodnej CKolo::CKolo(double R_t, double x_t, double y_t) : CPunkt(x_t,y_t) SetR(R_t); Konstruktor klasy CKolo wywołuje konstruktor klasy CPunkt, który jest odpowiedzialny za zainicjowanie tej części obiektu klasy CKolo, która pochodzi z klasy podstawowej CPunkt. Wartości x_t, y_t są przekazywane z konstruktora CKolo do konstruktora CPunkt, który zainicjuje nimi dane składowe klasy podstawowej. Dodatkowo inicjowana jest wartość promienia R poprzez funkcję SetR (w celu sprawdzenia poprawności wartości zadanego promienia). Należy pamiętać, że w przypadku, gdy konstruktor klasy podstawowej CPunkt nie zostanie przez nas wywołany jawnie w konstruktorze klasy pochodnej CKolo, operacja wywołania domyślnego konstruktora klasy CPunkt i tak zostałaby przeprowadzona dla domyślnych wartości x i y. implementacja funkcji zaprzyjaźnionych z klasą pochodną CKolo ostream & operator << (ostream & output, const CKolo & kolo) output << "Srodek kola = " << CPunkt(kolo) << ", R = " << kolo.r; return output; Funkcje zaprzyjaźnione z klasą podstawową nie są dziedziczone przez klasę pochodną. Tak więc w rozważanym przykładzie klasa pochodna CKolo nie może bezpośrednio wywołać zaprzyjaźnionej funkcji operatorowej klasy CPunkt przeciążającej operator wstawiania do strumienia <<. Istnieje jednak możliwość przeciążenia operatora << klasy CKolo w taki sposób, aby oprócz danych specyficznych dla obiektu koła, tzn. w naszym przykładzie promienia R, wyświetlone zostały również współrzędne środka koła. Operację taką umożliwia operacja rzutowania referencji do obiektu CKolo na klasę CPunkt. W wyniku takiego działania zostanie wywołany przeciążony operator << klasy CPunkt. deklaracja funkcji składowej obiektu jako funkcji stałej const void Drukuj () const; void CPunkt::Drukuj () const cout << "[" << x << ", " << y << "]"; Deklaracja funkcji składowej obiektu jako funkcji stałej const jest ważnym elementem programowania obiektowego. Wiąże się to z tym, że w przypadku deklaracji stałego obiektu pewnej klasy w kodzie programu, mamy możliwość nadania mu wartości jedynie w chwili jego tworzenia (poprzez konstruktor danej klasy), jednak wywołanie dowolnej z jego funkcji składowych 3

(nawet tych, które nie modyfikują wartości danych) nie jest dozwolone. Wyjątek stanowią funkcje zadeklarowane w obiekcie jako const zarówno w prototypie jak też w definicji definicji funkcji. Funkcje tak zdefiniowane nie mogą jednak modyfikować danych obiektu. Wykorzystanie klas CKolo i CPunkt w programie // ------------------------------------------------------------------------------ // // Czesc 1 - Wykorzystanie klasy CPunkt oraz CKolo w programie // ------------------------------------------------------------------------------ // CPunkt * ptrpunkt = 0; CPunkt punkta (30,50); CKolo * ptrkolo = 0; CKolo kolob (2.5,120,90); cout << "Czesc 1" << endl; cout << "--------------------------------------------------------------------------" << endl; cout << "Punkt A: " << punkta << endl; cout << "Kolo B: " << kolob << endl << endl; // Czesc 2 - Traktujemy kolo jako punkt ('widzimy' jedynie czesc z klasy podstawowej) cout << "Czesc 2" << endl; cout << "--------------------------------------------------------------------------" << endl; // Zad.1 Przypisanie adresu kola wskaznikowi ptrpunkt cout << "Kolo B (poprzez *ptrpunkt): " << *ptrpunkt << endl << endl; // Zad.2 Traktujemy kolob jako kolo (z rzutowaniem) // Przypisanie adresu kola wskaznikowi ptrpunkt // Rzutowanie wskaznika klasy podstawowej na wskaznik klasy pochodnej cout << "Kolo B (przez *ptrkolo): " << *ptrkolo << endl; cout << "Powierzchnia kola B (przez ptrkolo): " << ptrkolo->obliczobszar() << endl << endl; // Czesc 3 - Niebezpieczna operacja - Traktowanie punktu jako kola // Przypisanie adresu punktu wskaznikowi ptrpunkt ptrpunkt = &punkta; // Rzutowanie wskaznika klasy podstawowej na wskaznik klasy pochodnej cout << "Czesc 3" << endl; cout << "--------------------------------------------------------------------------" << endl; cout << "Punkt A (poprzez *ptrkolo): " << *ptrkolo << endl; cout << "Powierzchnia obiektu ptrkolo: " << ptrkolo->obliczobszar() << endl << endl; Do ważnych elementów przedstawionych w kolejnych częściach w programie możemy zaliczyć: sposób deklaracji obiektów klasy CPunkt i CKolo oraz odpowiednich wskaźników do tych obiektów CPunkt * ptrpunkt = 0; CPunkt punkta (30,50); CKolo * ptrkolo = 0; CKolo kolob (2.5,120,90); Powyższy kod przedstawia deklarację obiektu punkta. Wywołaniu konstruktora towarzyszy nadaje wartości współrzędnym x 4

oraz y punktu w taki sposób, że x = 30, y = 50. Deklaracja wskaźnika ptrpunkt do typu CPunkt połączona jest z inicjacją wartością 0 (co oznacza, że wskaźnik nie wskazuje w tej chwili na żaden obiekt klasy CPunkt). Wskaźnik ptrpunkt służy do wskazywania na obiekty klasy CPunkt. Podobne operacje są wykonane w odniesieniu do obiektu klasy CKolo oraz wskaźnika do typu CKolo. Zauważmy, że kolob jest obiektem klasy pochodnej CKolo, która dziedziczy dane i funkcje składowe klasy podstawowej CPunkt. sposób wykorzystania zaprzyjaźnionych funkcji operatorowych wstawiania do strumienia << cout << "Punkt A: " << punkta << endl; cout << "Kolo B: " << kolob << endl << endl; Wypisując obiekty klasy podstawowej i pochodnej wykorzystujemy odpowiednie zaprzyjaźnione funkcje operatorowe zaimplemetowane zarówno w klasie CPunkt jak i w klasie CKolo. "traktowanie kola jako punktu" (w wyniku takiej operacji 'widzimy' jedynie tą cześć danych i funkcji składowych, która należy do klasy podstawowej) a) Przypisanie adresu obiektu kolob wskaźnikowi ptrpunkt. W przypadku dziedziczenia publicznego zawsze możliwe jest przypisanie wskaźnikowi klasy podstawowej CPunkt wskaźnika klasy pochodnej CKolo. Operacja taka jest dozwolona, gdyż obiekt klasy pochodnej CKolo jest jednocześnie obiektem klasy podstawowej CPunkt. Jednak wskaźnik do klasy podstawowej CPunkt 'widzi' wyłącznie tę część obiektu klasy pochodnej CKolo, która znalazła się w nim w wyniku dziedziczenia z klasy podstawowej. Wykonana jest przez kompilator niejawna konwersja wskaźnika do klasy pochodnej CKolo na wskaźnik do klasy podstawowej CPunkt. b) cout << "Kolo B (poprzez *ptrpunkt): " << *ptrpunkt << endl << endl; Wykonanie operacji wypisania obiektu kolob z wykorzystaniem do tego celu wskaźnika ptrpunkt spowoduje, że zobaczymy na ekranie jedynie informację o współrzędnych środka koła. "traktowanie koła jako koła" (z wykorzystaniem operacji rzutowania) a) Przypisanie adresu obiektu kolob wskaźnikowi ptrpunkt. b) Rzutowanie wskaźnika klasy podstawowej CPunkt na wskaznik klasy pochodnej CKolo. c) cout << "Kolo B (przez *ptrkolo): " << *ptrkolo << endl; cout << "Powierzchnia kola B (przez ptrkolo): " << ptrkolo->obliczobszar() << endl << endl; W wyniku wykonania powyższych instrukcji wypisane zostaną wszystkie informacje dotyczące obiektu kolob (wywołana zostanie funkcja operatorowa przeciążona w klasie CKolo) oraz wypisane zostanie pole koła reprezentowanego przez obiekt kolob (czyli wywołana zostanie właściwa funkcja obliczająca pole koła zaimplementowana w klasie CKolo). "traktowanie punktu jako koła" (niebezpieczna operacja) a) ptrpunkt = &punkta; Przypisanie adresu obiektu punkta wskaźnikowi ptrpunkt. b) Przypisanie adresu punktu (tj. adresu znajdującego się w zmiennej wskaźnikowej ptrpunkt) czyli wykonanie operacji rzutowania wskaźnika klasy podstawowej CPunkt na wskaźnik klasy pochodnej CKolo. Formalnie nie istnieje bezpośrednia możliwość przypisania wskaźnikowi klasy pochodnej CKolo wskaźnika do klasy 5

podstawowej CPunkt. Przypisanie takie jest bardzo niebezpieczne. W tym przypadku kompilator nie przeprowadza konwersji typów. c) cout << "Punkt A (poprzez *ptrkolo): " << *ptrkolo << endl; cout << "Powierzchnia obiektu ptrkolo: " << ptrkolo->obliczobszar() << endl << endl; W pierwszej z powyższych instrukcji mamy do czynienia z próbą wypisania obiektu punkta klasy CPunkt za pomocą przeciążonego w klasie CKolo operatora << oraz zdereferowanego wskaźnika ptrkolo. W takiej sytuacji promień R ma wartość 0 lub przyjmuje pewną bliżej niezdefiniowaną wartość znajdującą się w pamięci pod adresem, który powinien zawierać daną składową R. Dzieje się tak dlatego, że składowa R w tym przypadku nie istnieje (wskaźnik ptrkolo wskazuje bowiem na obiekt klasy CPunkt). Podobnie w drugiej instrukcji, wykorzystujemy wskaźnik ptrkolo (wskazujący w rzeczywistości na obiekt klasy CPunkt) do obliczenia pola obszaru koła. Wyznaczona powierzchnia ma wartość 0 lub inną wartość niezdefiniowaną, gdyż do stosownych obliczeń użyto nieokreśloną bliżej wartość promienia R. Co więcej należy pamiętać, że wywołanie w programie nie istniejącej funkcji składowej klasy (w tym przypadku funkcji, która nie istnieje w klasie CPunkt) może spowodować zakończenie działania programu i wyświetlenie komunikatu o błędzie. Zadanie 2 Cześć A: Implementacja klas. Napisać program umożliwiający tworzenie oraz dalsze wykorzystanie obiektów dwóch klas: COsoba oraz CPracownik. Klasą bazową jest klasa COsoba. W klasie tej przewidziane są chronione dane składowe: nazwisko (typu string) oraz wiek (typu int; wiek osoby powinien być z zakresu od 0 do 120). W klasie powinien zostać zdefiniowany konstruktor domyślny, który umożliwia również nadanie pewnych domyślnych wartości danym składowym klasy (nazwisko = "", wiek = 0). Wykorzystuje on odpowiednie funkcje dostępowe Set zdefiniowane w obiekcie (funkcje te nadają wartości danym składowym w klasie oraz sprawdzają poprawność zaproponowanych przez użytkownika danych). Ponadto w klasie powinny zostać zdefiniowane funkcje dostępowe Get (określone jako funkcje stałe), funkcja stała Drukuj wyświetlająca informacje o osobie na ekranie oraz działający w podobny sposób przeciążony operator wstawiania do strumienia <<. Drugą klasą jest klasa CPracownik, która dziedziczy dane i funkcje składowe klasy COsoba. Co więcej w klasie tej przewidziana jest prywatna dana składowa: zarobek_mies (typu int; zarobek pracownika podany w walucie PLN powinien być z zakresu od 0 do 5000). W klasie CPracownik powinien się znaleźć również odpowiednio: konstruktor domyślny, który umożliwia również nadanie pewnych domyślne wartości danym składowym klasy (nazwisko = "", wiek = 0, zarobek_mies = 0), funkcje Set, stałe funkcje Get, stała funkcja Drukuj wyświetlająca informacje o pracowniku na ekranie oraz działający w podobny sposób przeciążony operator wstawiania do strumienia <<. Dodatkowo w klasie powinna zostać zdefiniowana funkcja składowa Dochod_Roczny. Zadaniem funkcji jest przekazywanie do programu (przez return) rocznego dochodu uzyskanego przez pracownika (12 x zarobek_mies). Cześć B: Zadania testowe w programie. 1) Zadeklaruj w programie obiekt osobaa typu COsoba (przyjmujemy, że dane o osobie będą określone w dalszej części programu) oraz obiekt praca typu CPracownik (dane o pracowniku nadane zostaną przy tworzeniu obiektu). 2) Nadaj wartości danym obiektu osobaa wykorzystując do tego funkcje dostępowe Set. 3) Wypisz na ekranie dane o osobie osobaa wykorzystując do tego funkcję Drukuj oraz dane o pracowniku praca wykorzystując do tego przeciążony operator <<. 4) Zadeklaruj wskaźnik ptrosoba do typu COsoba oraz ptrpracownik do typu CPracownik. 5) Przypisz adres obiektu osobaa dla wskaźnika ptrosoba oraz adres obiektu praca dla wskaźnika ptrpracownik. 6) Wypisz na ekranie dane o osobie osobaa oraz pracowniku praca wykorzystując do tego funkcję Drukuj oraz wskaźniki ptrosoba i ptrpracownik. 7) Zadeklaruj wskaźnik ptr1 do typu COsoba i zainicjuj go adresem obiektu praca. 8) Wypisz na ekranie informacje o pracowniku praca wykorzystując do tego przeciążony operator << oraz zdereferowany wskaźnik ptr1. 9) Zadeklaruj wskaźnik ptr2 do typu COsoba i zainicjuj go adresem obiektu praca. 10) Zadeklaruj wskaźnik ptr3 do typu CPracownik. 11) Wykonaj operację rzutowania wskaźnika ptr2 do klasy COsoba na wskaźnik ptr3 klasy CPracownik. 12) Wykorzystując operator << oraz zdereferowany wskaźnik ptr3 wypisz na ekranie informacje o pracowniku praca. 13) Przypisz adres ptrosoba dla wskaźnika ptr2. 14) Wykonaj operację rzutowania wskaźnika ptr2 na wskaźnik ptrpracownik. 15) Wykorzystując operator << oraz wskaźnik ptrpracownik wypisz na ekranie informacje o pracowniku. 6