• Nie Znaleziono Wyników

Wykład 8 Dziedziczenie jednobazowe

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 8 Dziedziczenie jednobazowe"

Copied!
1
0
0

Pełen tekst

(1)

Wykład 8

Dziedziczenie jednobazowe

1. Dziedziczenie metod i operatorów z przedefiniowaniem

2. Dziedziczenie klas z polami dynamicznymi - definicje konstruktorów zwykłych i kopiowania, destruktorów, przeciążenie operatorów przypisania=, dziedziczenie metod bez/z przedefiniowaniem

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 1

(2)

1. Dziedziczenie metod i operatorów z przedefiniowaniem (pokrywaniem) Przykład 8.1

Należy wykonać w klasach: bazowej punkt i pochodnej kolo operatory przedrostkowe i przyrostkowe: operator++ oraz operator--, dokonując przedefiniowania.

Metody te powinny zwiększać lub zmniejszać pola x i y w klasie punkt i dodatkowo pole promien w klasie kolo.

W definicji operatorów w klasie kolo wykorzystać metody-operatory dziedziczone z klasy punkt, np.

punkt::operator++();

w definicji operatora ++

w klasie kolo.

...

#include "kolo5_3.h"

#include "punkt5_3.h"

void wyswietl(kolo&, char *napis);

void wyswietl(punkt&, char *napis);

void wyswietl(float);

void main() {

clrscr();

{ kolo kolo1(2, 2, 3), kolo2(1, 5, 6);

punkt punkt1 (2, 3), punkt2(2, 8);

wyswietl(kolo1, "kolo1: "); wyswietl(kolo2, "kolo2: ");

wyswietl(punkt1, "punkt1: "); wyswietl(punkt2, "punkt2: ");

wyswietl(++kolo1, "++kolo1: "); wyswietl(++kolo2, "++kolo2: ");

wyswietl(++punkt1, "++punkt1: "); wyswietl(++punkt2, "++punkt2: ");

wyswietl(--kolo1, "--kolo1: "); wyswietl(--kolo2, "--kolo2: ");

wyswietl(--punkt1, "--punkt1: "); wyswietl(--punkt2, "--punkt2: ");

wyswietl(kolo1--, "kolo1--: "); wyswietl(kolo2--, "kolo2--: ");

wyswietl(punkt1--, "punkt1--: "); wyswietl(punkt2--, "punkt2--: ");

wyswietl(kolo1++, "kolo1++: "); wyswietl(kolo2++, "kolo2++: ");

wyswietl(punkt1++, "punkt1++: "); wyswietl(punkt2++, "punkt2++: ");

wyswietl(kolo1.odleglosc(kolo2));

float a = (kolo1--).odleglosc((kolo2++));

wyswietl(a);

wyswietl(kolo1.odleglosc(kolo2));

} }

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 2

(3)

class punkt //plik nagłówkowy punkt5_3.h klasy punkt { float x,y;

public: punkt (float = 0.0, float = 0.0);

punkt(punkt&);

~punkt();

punkt& operator++();

punkt& operator--();

punkt& operator++(int); //fikcyjny parametr dla przyrostkowego ++

punkt& operator--(int); // podobnie jak wyżej dla -- float odleglosc(punkt&) const;

static int info();

float& odcieta();

float& rzedna();};

#include "punkt5_3.h" //plik nagłówkowy kolo5_3.h klasy kolo class kolo : public punkt

{ float promien;

public: kolo (float = 0.0, float = 0.0,float = 0.0);

kolo(kolo&);

~kolo();

kolo& operator ++(); //pokrywanie metod operatorowych kolo& operator --();

kolo& operator ++(int); //fikcyjny operator dla przyrostkowego ++

kolo& operator --(int); //podobnie jak wyżej dla -- static int info();

float& p_promien();};

#include "punkt5_3.h" //plik punkt5_3.cpp z definicjami metod klasy punkt ...

punkt& punkt::operator++() { x += 1; y += 1; return *this; } punkt& punkt::operator++(int) { x += 1; y += 1; return *this; }

#include "kolo5_3.h" //plik kolo5_3.cpp z definicjami metod klasy kolo

#include "punkt5_3.h"

...

kolo& kolo::operator ++()

{ punkt::operator++(); //wywołanie dziedziczonej metody

promien+=1;

return *this; }

kolo& kolo::operator ++(int)

{ punkt::operator++(3); //wywołanie dziedziczonej metody

promien+=1;

return *this; }

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 3

(4)

2. Dziedziczenie klas z polami dynamicznymi - definicje konstruktorów zwykłych i kopiowania, destruktorów, przeciążenie operatorów przypisania=, dziedziczenie metod bez/z przedefiniowaniem

Przykład 8.2

Przykład prezentuje dziedziczenie metod i operatorów klas zawierających pole typu dynamiczna dwuwymiarowa tablica elementów typu int. Dotyczy on klasy bazowej figura (wyklad6.doc /przykład 6.2) oraz klasy pochodnej figura_1, która odwzorowuje zakres indeksów tablicy Figura dla:

 wierszy z 0  max_w-1 do pocz_w  pocz_w+max_w-1

 kolumn z 0  max_kol-1 do pocz_kol  pocz_kol+max_kol-1.

Konstruktory klasy figura_1 należy zdefiniować za pomocą listy argumentów. Definiowanie destruktora w klasie figura_1 nie jest konieczne, gdyż pole dynamiczne Figura będzie zwolnione przez destruktor jawny klasy bazowej figura wywołany z destruktora domniemanego klasy pochodnej figura_1.

Klasę figura należy zmodyfikować następująco:

* zadeklarować składowe prywatne jako składowe protected

* zdefiniować operator= umożliwiający tworzenie kopii danych w obiekcie po lewej stronie operatora. Należy pamiętać, że domniemany operator przypisania kopiuje tylko zawartość obiektu, czyli w przypadku pól dynamicznych skopiuje jedynie ich adresy. Wtedy po przypisaniu dwa obiekty korzystają z tych samych pól dynamicznych. Pola dynamiczne obiektu lewego pozostaną w pamięci i będą niedostępne

W klasie figura_1 należy wprowadzić lub zmienić, korzystając z dziedziczenia:

* operator()(int, int), służący do indeksowania dwuwymiarowej tablicy Figura w odwzorowanym zakresie indeksów wierszy i kolumn,

* w metodzie przesun uwzględnić nowy zakres indeksów

 oraz zadeklarować i zdefiniować operator=, pełniący podobną rolę do operatora = w klasie figura, gdyż operatory przypisania nie są dziedziczone.

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 4

(5)

#include "fig5_4.h"

#include "fign5_4.h"

void wprowadz_punkty(figura_1&); //przekazanie przez referencje-zapis void wyswietl(const figura_1); //przekazanie przez wartość- odczyt void main()

{ do

{ figura_1 wielokat(5,2,10,15), w(0,0,0) ; //...

figura p(5,2);

p = wielokat; //uwaga 1

//wielokat = p;

//uwaga 2

w = wielokat; //uwaga 3

cout<<"Nalezy wprowadzic wspolrzedne (x,y) roznych punktow\n";

//...

wprowadz_punkty(wielokat);

//...

wielokat.rysuj();

//...

wyswietl(wielokat);

//...

cout<<" Jesli koniec, nacisnil ESC, dalej - dowolny klawisz\n";

}while (getch() != 27);

}

/*

Uwagi do programu:

1. konwersja obiektu wielokat do klasy bazowej figura i wywołanie operatora przeciążonego= z klasy figura, który kopiuje pole dynamiczne Figura;

domniemany operator= skopiowałby tylko część obiektu wielokat (część typu figura) do obiektu p; wówczas p i wielokat posiadałyby adres tej samej tablicy dynamicznej

2. błąd, gdy nie istnieje konwersja konstruktorowa figura_1::figura_1(figura), tworząca z obiektu p typu figura obiekt klasy figura_1

1.

wywołanie operatora = z klasy figura_1, który kopiuje pole dynamiczne Figura;

domniemany operator = spełniłby rolę podobną jak w klasie figura (uwaga 1).

*/

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 5

(6)

void wprowadz_punkty(figura_1& wielokat) {

int i = wielokat.podaj_p_w();

int jj = wielokat.podaj_p_k();

int ile_w = wielokat.podaj_w(), a;

int ile_kol = wielokat.podaj_k();

for (; i < ile_w; i++) //i już przypisane for (int j = jj; j < ile_kol; j++)

{ cout << "Podaj wielokat[" << i <<",”<< j << "]:= ";

cin >> a;

wielokat << a;

} }

void wyswietl(const figura_1 wielokat) {

int i = wielokat.podaj_p_w();

int jj = wielokat.podaj_p_k();

int ile_w = wielokat.podaj_w();

int ile_kol = wielokat.podaj_k(); //...

for (; i < ile_w; i++) //i już przypisane { for(int j = jj; j < ile_kol; j++)

//referencyjny operator() na kopii obiektu przekazanego przez wartość cout << setw(15) << "Wielokat[" << i << "," << j << "] " <<

setw(5) << wielokat(i, j);

cout<<'\n';

} }

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 6

(7)

class figura //plik nagłówkowy fig5_4.h klasy bazowej figura {

protected: int ile;

int max_w;

int max_kol;

int* Figura;

void kopia(const figura&) int koniec(int,int) const;

public: figura (int = 0, int=0);

figura(figura&);

~figura();

void przesun (int, int, int);

void rysuj() const;

int podaj_wsp_x() const;

int podaj_wsp_y() const;

int podaj_ile() const;

figura& operator<<(int);

int& operator()(int, int) const;

figura& operator=(const figura&);

};

#include "fig5_4.h" //plik nagłówkowy klasy pochodnej figura_1

class figura_1: public figura {

int pocz_w; //indeksy początkowe wierszy i kolumn

int pocz_kol; //czyli dodatkowe składowe

public:

figura_1 (int = 0, int = 0, int = 0, int = 0);

figura_1(figura_1&);

~figura_1(); //nie jest konieczny- nie ma nowych pól dynamicznych void przesun (int, int, int); //metoda pokryta

int podaj_p_w() const; //nowe metody int podaj_p_k() const;

int podaj_w() const;

int podaj_k() const;

int& operator()(int, int) const; //operator pokryty

figura_1& operator=(const figura_1&); //operator pokryty bez dziedziczenia };

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 7

(8)

#include "fig5_4.h" //plik fig5_4.cpp z definicjami metod klasy figura

... // metody zaprezentowane w pliku wyklad6.doc, przykład 6.2

void figura::kopia(const figura& p) // metoda do kopiowania pól klasy figura {

if (coreleft() < p.max_wp.max_kol*sizeof(int)) exit(1);

ile = 0;

max_w = p.max_w;

max_kol = p.max_kol;

Figura = new int [max_wmax_kol];

for (int i=0; i<max_w; i++) for (int j=0; j<max_kol; j++) this << p(i, j);

}

figura::figura(figura& p) {

kopia(p);

}

figura& figura::operator= (const figura& p) {

cout<<"operator przypisania figura\n";

if (this != &p) //przypisywane, gdy różne obiekty klasy figura {

delete Figura; //usuwa się tablice w obiekcie po lewej stronie kopia(p);

} //operatora przypisania i tworzy kopie tablicy

return (*this); //z obiektu po prawej stronie instrukcji przypisania

}

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 8

(9)

#include "fign5_4.h" // plik fign5_4.cpp z definicjami metod klasy figura_1 ...

figura_1::figura_1 (int xx, int yy, int w, int k) : figura(xx,yy), pocz_w(w), pocz_kol(k) { } figura_1::figura_1(figura_1&p) : figura(p),

pocz_w(p.pocz_w), pocz_kol(p.pocz_kol) { }

void figura_1::przesun (int d, int ile_w, int ile_kol) {

figura :: przesun(d, ile_w - pocz_w, ile_kol - pocz_kol);

}

int& figura_1::operator()(int ile_w, int ile_kol) const {

return figura :: operator() (ile_w - pocz_w, ile_kol - pocz_kol);

}

figura_1 & figura_1::operator= (const figura_1& p) {

if (this != &p) //przypisywane, gdy różne obiekty klasy figura_1 {

delete Figura; //usuwa się tablice w obiekcie this po lewej stronie

kopia(p); //operatora przypisania i tworzy kopie tablicy z obiektu p } // przekształconego do klasy figura po prawej stronie instrukcji przypisania pocz_w = p.pocz_w;

pocz_kol = p.pocz_kol;

return (*this);

}

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 8

Politechnika Wrocławska 9

Cytaty

Powiązane dokumenty

Wspólnie podsumujcie, jakie czynności trzeba wykonać, by za pomocą trzech cięć wykonać figurę niemoż- liwą (możesz zacząć od ucznia, któremu udało się rozwiązać to

Z bolącą nogą, poruszając się o dwóch kulach rozpoczęło się na nowo jej zesłańcze życie.. Do Polski wraz z rodzina powróciła 4 marca

Wymienić funkcje w pracy snpłeaznej po zwolnieniu z wojska do chwili obecnej% :..... Stan cywilny

Poza ekranizacjami powieści związanych bezpośrednio ze Stambułem i historii, które opowiadają o samym mieście, jest ono często tłem dla prezentowanych

Figury polegające na modyfikacji zapisu są pomysłem bardzo starym i ma- jącym wiele źródeł. Jednym z nich są dawne chronogramy, czyli pisane frazy, których pewne litery mogły

Na tej płaszczyźnie człowiek nadal jest celem nadrzędnym, ale zostaje „wbudowany” w architektoniczne konstrukty, do tego stopnia, Ŝe jego samego rozwaŜać moŜna jako

konwersja obiektu wielokat do klasy bazowej figura i wywołanie operatora przeciążonego= z klasy figura, który kopiuje pole dynamiczne Figura;. domniemany

Definiowanie destruktora w klasie figura_1 nie jest konieczne, gdyż pole dynamiczne Figura będzie zwolnione przez destruktor jawny klasy bazowej figura wywołany z destruktora