• Nie Znaleziono Wyników

Wykład 12 Polimorfizm c.d.

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 12 Polimorfizm c.d."

Copied!
16
0
0

Pełen tekst

(1)

Wykład 12 Polimorfizm c.d.

1. Metody czysto wirtualne, klasy abstrakcyjne

2. Obiektowe struktury danych - stos jako dynamiczna tablica wskaźników na dynamiczne obiekty

3. Obiektowa struktura danych – stos jako dynamiczna rekurencyjna struktura danych

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 11Politechnika Wrocławska

1

(2)

1. Metody czysto wirtualne, klasy abstrakcyjne

Metody czysto wirtualne są deklarowane z inicjalizacją zerem:

virtual void wyswietl () = 0;

Klasa zawierająca co najmniej jedną taką funkcję jest klasą abstrakcyjną.

Oznacza to, że nie można tworzyć obiektów jej typu.

Funkcja czysto wirtualna musi być przedefiniowana w klasie pochodnej, albo nowo zadeklarowana pochodna klasa będzie ją dziedziczyć, stąd stanie się również klasą abstrakcyjną.

Klasa abstrakcyjna służy do uogólnienia cech wszystkich jej następców w danej rodzinie za pomocą metod czysto wirtualnych. Wystarczy korzystać ze wskaźników lub referencji do klasy abstrakcyjnej, aby można było zastosować metodę czysto wirtualną, która w czasie działania programu zostanie zastąpiona przedefiniowaną metodą wywołaną przez aktualnego następcę klasy abstrakcyjnej.

Stąd dzięki klasie abstrakcyjnej można ograniczyć:

liczbę innych klas

i funkcji

obsługujących całą rodzinę klas dziedziczących od klasy abstrakcyjnej.

W dalszej części wykładu przedstawiono korzyści wynikające z korzystania z klas abstrakcyjnych ( przykłady 12.1 - 12.3).

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 11Politechnika Wrocławska

2

(3)

Przykład 12.1

punkt

ramka napis

punkt

ramka napis

n_ramka

abstr klasa

abstrakcyjna

klasa wirtualna

1) 2)

W przykładzie zastosowano klasę abstrakcyjną abstr w rodzinie z klasą wirtualną punkt z przykładu 10.2 z wykładu 10, która uogólnia cechy klasy punkt za pomocą czystych metod wirtualnych i jest praprzodkiem wszystkich klas. Zawiera ona: czyste metody wirtualne: wyswietl, przeciążone operatory-- i ++ oraz wirtualny zwykły destruktor. Stąd wszystkie klasy posiadają wirtualny destruktor, gdyż został ustalony destruktor wirtualny w klasie abstr.

Klasa punkt dziedziczy od klasy abstrakcyjnej abstr i stanowi klasę wirtualną dla klas: ramka, napis oraz n_ramka jak w przykładzie 10.2 z wykładu 10. Klasa punkt posiada przedefiniowane metody wirtualne: operatory++ i -- oraz metodę wyswietl dziedziczoną bez przedefiniowania przez wszystkie klasy pochodne! Posiada wirtualny destruktor oraz metody wirtualne: p_atrybuty (dla klasy n_ramka) i pozostałe jak w przykładzie 11.2.

W klasie ramka przedefiniowano metody wirtualne: operatory ++ i --, metody dostępu p_dlugosc i p_wysokosc oraz metodę rysuj. Klasa ramka ma wirtualny destruktor i dziedziczy od klasy punkt metody wirtualne p_wiersz i p_atrybuty (niewykorzytane) oraz metodę wyswietl (wykorzystana).

W klasie napis przedefiniowano metody wirtualne: operatory++ i --, metody dostępu p_dlugosc i p_wiersz oraz metodę rysuj. Klasa napis ma wirtualny destruktor i dziedziczy od klasy punkt metody wirtualne p_wysokosc i p_atrybuty (niewykorzystane) oraz metodę wyswietl (wykorzystana).

Klasa n_ramka dziedziczy bezpośrednio bez przedefiniowania metody wirtualne: od klasy punkt: wyswietl, od klasy napis: p_dlugosc, p_wiersz, od klasy ramka: p_wysokosc, p_dlugosc. Posiada przedefiniowane metody wirtualne: operatory++ i --, rysuj, p_atrybuty. Klasa ma wirtualny destruktor.

Zofia Kruczkiewicz Języki i metody programowania, język C 2, Wykład 11Politechnika Wrocławska

3

(4)

Rozkład metod rodziny punkt z klasą abstrakcyjną abstr

klasy Metody wirtualne czyste metody wirtualne zwykłe metody wirtualne

przedefiniowane metody zwykłe

abstr virtual void wyswietl(char*) virtual abstr& operator++() virtual abstr& operator--()

~abstr()

punkt virtual void rysuj()

virtual int p_atrybuty() virtual int _dlugosc() virtual int p_wysokosc() virtual char* p_wiersz()

~punkt()

void wyswietl(char* ) abstr& operator++() abstr& operator--()

punkt (int=0,int=0) punkt(punkt&) int& dcieta() int& rzedna()

float odleglosc (punkt)

ramka ~ramka() abstr& operator++()

abstr& operator--() int p_dlugosc() int p_wysokosc() void rysuj()

ramka (int,int,int,int) ramka(ramka&)

napis ~napis() abstr& operator++()

abstr& operator--() char* p_wiersz() int p_dlugosc() void rysuj()

napis (int,int,char*) napis(napis&)

napis& operator=

(napis&)

n_ramka ~n_ramka() abstr& operator++()

abstr& operator--() void rysuj()

int p_atrybuty()

n_ramka

(int,int,int,int,char*,int) n_ramka(n_ramka&)

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

Politechnika Wrocławska 4

(5)

#include "nram7_2.h"

void wyswietl(punkt&, char * kom);

void wyswietl(punkt*, char * kom);

void wyswietl(float, char * kom);

void main()

{ { n_ramka n_r1(36,5,19,8,"napis w ramce_1",0x3A), n_r2(54,3,19,5,"napis w ramce_2",0x1B);

ramka r1(50,12,10,8), r2(60,9,10,5);

napis n1(50,21,"napis1"), n2(63,18,"napis2");

punkt p1 (2,5), p2(2,8);

/* Pierwszy sposób -

jedna funkcja wywołuje wirtualne metody, dynamicznie dołączane zależnie od podstawionego obiektu przez referencje */

wyswietl(n_r1," n_r1\n"); wyswietl(n_r2," n_r2\n");

wyswietl(r1,"\n r1\n"); wyswietl(r2,"\n r2\n");

wyswietl(n1,"\n n1\n"); wyswietl(n2,"\n n2\n");

wyswietl(p1,"\n p1\n"); wyswietl(p2,"\n p2\n");

/* Drugi sposób -

jedna funkcja wywołująca wirtualne metody, dynamicznie dołączane zależnie od podstawionego obiektu przez wskaźnik*/

wyswietl(&n_r1," --n_r1\n");

wyswietl(&r1,"\n --r1\n");

wyswietl(&n1,"\n --n1\n");

wyswietl(&p1,"\n --p1\n");

/* Trzeci sposób -

pierwsze: typem wskaźnika p jest klasa abstrakcyjna abstr, stąd kompilator poszukuje metody wywoływanej (wyswietl) w tej klasie. Ponieważ jest to metoda wirtualna, to wywołuje przedefiniowane metody wirtualne dynamicznie dołączane z klas wywołujących obiektów-następców, których adresy są we wskaźniku p–w tym wypadku jest to metoda przedefiniowana jedynie w klasie wirtualnej punkt;

drugie: metody wirtualne dynamicznie dołączane z klas wywołujących obiektów–w tym wypadku jest to wirtualna metoda dziedziczona od klasy wirtualnej punkt;*/

abstr* p;

p=&n_r2; p->wyswietl(" ++n_r2\n"); n_r2.wyswietl(" ++n_r2\n");

p=&r2; p->wyswietl("\n ++r2\n"); r2.wyswietl("\n ++r2\n");

p=&n2; p->wyswietl("\n ++n2\n"); n2.wyswietl("\n ++n2\n");

p=&p2; p->wyswietl("\n ++p2\n"); p2.wyswietl("\n ++p2\n");

//wywołanie metody dziedziczonej odleglosc od klasy punkt

wyswietl(n_r1.odleglosc(n_r2),"Odleglosc miedzy ramkami z napisem: ");

wyswietl(r1.odleglosc(r2),"Odleglosc miedzy ramkami: ");

wyswietl(n1.odleglosc(n2),"Odleglosc miedzy napisami: ");

wyswietl(p1.odleglosc(p2),"Odleglosc miedzy punktami: ");

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

(6)

n_r1.rzedna()+= 2; //zmiana współrzędnej y napisu metodą klasy punkt n_r2= n_r1; //wywołanie przeciążonego operatora = z klasy napis

// przez domniemany operator = klasy n_ramka wyswietl(n_r1.odleglosc(n_r2), "Odleglosc miedzy napisami: ");

wyswietl(n_r1," n_r1\n"); wyswietl(n_r2," n_r2\n");

n2.rzedna()+= 2; //zmiana współrzędnej y napisu metodą klasy punkt n1= n2; //wywołanie przeciążonego operatora = z klasy napis wyswietl(n1.odleglosc(n2),"Odleglosc miedzy napisami: ");

wyswietl(n1,"\n n1\n"); wyswietl(n2,"\n n2\n");

} }

/* uniwersalna metoda do wyświetlania pól całej rodziny obiektów: punkt, ramka, napis, n_ramka dzięki:

 przekazywaniu obiektów przez referencje

 zastosowaniu polimorfizmu, czyli wywoływaniu metod wirtualnych: p_dlugosc, p_wiersz, p_wysokosc, p_atrybuty */

void wyswietl(punkt& p, char *kom) {

cout << "Atrybuty: " << p.p_atrybuty();

cout << " Wiersz: " << p.p_wiersz();

cout << " Dlugosc, Wysokosc: "<<p.p_dlugosc()<< ", "<<p.p_wysokosc()<<" ";

cout << " Wspolrzedne: " << p.odcieta() << " "<< p.rzedna() <<kom;

p.rysuj();

}

/* uniwersalna metoda do wyświetlania pól całej rodziny obiektów: punkt, ramka, napis oraz n_ramka dzięki:

 przekazywaniu obiektów przez wskaźnik

 zastosowaniu polimorfizmu, czyli wywoływaniu metod wirtualnych: p_dlugosc, p_wiersz, p_wysokosc, p_atrybuty i operatora wirtualnego --*/

void wyswietl(punkt* p, char *kom) {

--(*p);

cout << "Atrybuty: " << (*p).p_atrybuty();

cout << " Wiersz: " << (*p).p_wiersz();

cout<<" Dlugosc,Wysokosc: "<<p->p_dlugosc()<<", "<<p->p_wysokosc()<<"” ; cout << " Wspolrzedne: " << p->odcieta() << " "<< p->rzedna() <<kom;

p->rysuj();

}

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

(7)

class abstr

{ public: virtual ~abstr() { }

virtual void wyswietl(char*) = 0;

virtual abstr& operator++() = 0;

virtual abstr& operator--() = 0;

};

#include "abstr7_2.h"

...

class punkt: public abstr { protected: int x,y;

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

punkt(punkt&);

~punkt();

int& odcieta(); { return x;}

int& rzedna(); { return y;}

float odleglosc(punkt) const;

//metody wirtualne przedefiniowane klasy abstrakcyjnej

void wyswietl(char* ); //definicja jak w przykładzie 11.2 abstr& operator++(); { x +=1; y+=1; return *this;}

abstr& operator--(); { x -=1; y-=1; return *this;}

//metody wirtualne

virtual void rysuj() {gotoxy(x,y); putch('*');}

virtual int p_atrybuty() const {return -1;}

virtual int p_dlugosc() const {return -1;}

virtual int p_wysokosc() const {return -1;}

virtual char* p_wiersz() const {return "Brak wiersza";}

};

#include "punkt7_2.h"

...

class ramka: public virtual punkt { protected: int dlugosc,wysokosc;

public: ramka (int=0,int=0,int=10,int=10);

ramka(ramka&);

~ramka();

//pokrywanie metod wirtualnych z klasy punkt int p_dlugosc() const;

int p_wysokosc() const;

void rysuj();

/*pokrywanie metod operatorowych wirtualnych - wynik działania funkcji jest referencyjny, stąd referencja do obiektu *this, czyli klasy ramka zgodnej z klasa abstr

abstr& operator ++();

abstr& operator --();};

#include "punkt7_2.h"

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

(8)

...

class napis : public virtual punkt { protected: int dlugosc;

char *wiersz;

int kopiuj(char*,int);

public: napis (int=1,int=1,char* ="");

napis(napis&);

~napis();

napis& operator=(napis&);

//pokrywanie metod wirtualnych z klasy punkt char* p_wiersz() const;

int p_dlugosc() const;

void rysuj();

/*pokrywanie metod operatorowych wirtualnych - wynik działania funkcji jest referencyjny, stąd referencja do obiektu *this, czyli klasy napis zgodnej z klasą abstr*/

abstr& operator++();

abstr& operator--();

};

#include "napis9_2.h"

#include "ramka9_2.h"

...

class n_ramka : public napis, public ramka { protected: int atrybuty;

public: n_ramka(int=0,int=0,int=1,int=1,char* =””,int=0);

n_ramka(n_ramka&);

~n_ramka();

//pokrywanie metod wirtualnych z klasy punkt int p_atrybuty() const;

//pokrywanie metod wirtualnych z klas ramka i napis void rysuj();

/*pokrywanie metod operatorowych wirtualnych - wynik działania funkcji jest referencyjny, stąd referencja do obiektu *this, czyli klasy n_ramka zgodnej z klasą abstr*/

abstr& operator++();

abstr& operator--();

};

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

(9)

2. Obiektowe struktury danych - stos jako dynamiczna tablica wskaźników na dynamiczne obiekty

Przykład 12.2

ab *elem ile

punkt ramka

n_ramka napis*wiersz

*wiersz elem

wiersz

wiersz 3)

Obiekt typu stos zawiera dynamiczną tablicę wskaźników na obiekty dziedziczące po klasie abstrakcyjnej abstr.

Obiekt typu stos umożliwia tworzenie grup obiektów np. należących do wspólnej rodziny i ułatwia przetwarzanie ich ograniczając kod źródłowy programu. Na rysunku z przykładu 12.2 obszar zaznaczony przerywaną linią wyznacza obiekty luźno osadzone w programie z przykładu 12.1. Wstawianie i usuwanie obiektów do tablicy odbywa się zgodnie z algorytmem stosu: ostatnio wstawiony obiekt jest usuwany jako pierwszy. Wskaźniki obiektów, umieszczone w tablicy, stanowią spójny blok danych i operacje wstawiania odbywają się na końcu bloku, za ostatnio wstawionym elementem, natomiast usuwany jest zawsze ostatni element z bloku wstawionego do tablicy.

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

(10)

#include "nram7_2.h"

#include "stos7_3.h"

#include <iostream.h>

#include <conio.h>

void wyswietl(punkt&, char * kom);

void wyswietl(float, char * kom);

void main()

{ clrscr(); { n_ramka *n_r1, *n_r2;

ramka * r1, *r2;

napis * n1, *n2;

punkt * p1, *p2;

abst* p;

stos Stos(8);

n_r1= new n_ramka(36,10,19,8,"napis w ramce_1",0x3A);

Stos.wstaw(n_r1);

n_r2 = new n_ramka(54,8,19,5,"napis w ramce_2",0x1B);

Stos.wstaw(n_r2);

r1 = new ramka(50,12,10,8); Stos.wstaw(r1);

r2 = new ramka(60,9,10,5); Stos.wstaw(r2);

n1 = new napis(50,21,"napis1"); Stos.wstaw(n1);

n2 = new napis(63,18,"napis2"); Stos.wstaw(n2);

p1 = new punkt(12,13); Stos.wstaw(p1);

p2 = new punkt(12,8); Stos.wstaw(p2);

/*dzięki wirtualnej metodzie wyswietl klasy abstr wywoływanej w metodzie wyswietl stosu i przedefiniowanej w klasach pochodnych obiektów wstawionych do stosu*/

Stos.Dla_kazdego();

while (!Stos.pusty())

{ //usuwanie z “początku” struktury - ostatni wstawiony i jako pierwszy usuwany p = Stos.usun();

--(*p); --(*p); //dzięki polimorfizmowi klasy abstrakcyjnej wyswietl(*((punkt*)p),""); //dzięki polimorfizmowi klasy wirtualnej punkt wyswietl(((punkt*)p)->odleglosc(*n_r1),"");

}

Stos.wstaw(n_r1); Stos.wstaw(n_r2);

Stos.wstaw(r1); Stos.wstaw(r2);

Stos.wstaw(n1); Stos.wstaw(n2);

Stos.wstaw(p1); Stos.wstaw(p2);

Stos.Dla_kazdego();

/* dzięki polimorfizmowi klasy abstrakcyjnej usuwanie elementów stosu, pochodnych klasy abstr! - wywołany destruktor stosu usuwa każdy z obiektów wstawionych do stosu dzięki wirtualnemu destruktorowi klasy abstr i przedefiniowanym destruktorom klas pochodnych wstawionych do stosu*/ } }

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

(11)

#ifndef STOS.H //plik stos7_3.h

#define STOS.H

#include "abstr7_2.h"

#include <stdlib.h>

const maxN= 8;

typedef abstr* ab;

class stos

{ ab *elem; //elem jako wskaźnik dla dynamicznej tablicy wskaźników ab int ile; // liczba elementów wstawionych do stosu,

int rozmiar; // maksymalny rozmiar tablicy public:

stos(int max)

{ max<=0 ? (rozmiar= maxN) : (rozmiar= max);

elem = new ab [rozmiar]; ile = 0;}

~stos();

int pusty() {return ile == 0;}

//wstawianie na “początku” struktury-realizacja przez wstawianie na koniec tablicy void wstaw(ab x)

{if ( ile < rozmiar) elem[ile++] = x;}

*/usuwanie z “początku” struktury - ostatni wstawiony i jako pierwszy usuwany zrealizowane przez usuwanie ostatniego elementu z tablicy*/

ab usun()

{ if (ile>0) return elem[--ile];

else return NULL;}

void Dla_kazdego();

};

#endif

//definicje poza blokiem deklaracji ze względu na zastosowane instrukcje pętli stos::~stos()

{int i= ile;

while(i>0) delete elem[--i];

delete [ ] elem;

}

void stos::Dla_kazdego() { char w[25];

int i= ile;

while(i>0) //wywołanie wirtualnej metody z klasy abstr przedefiniowanej u //każdego z następców tej klasy

elem[--i]->wyswietl(itoa(i, w,10); }

3. Obiektowa struktura danych – stos jako dynamiczna rekurencyjna struktura danych

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

(12)

Przykład 12.3

poczatek

punkt ramka

n_ramka napis x,y

dlugosc wiersz

x, y

wysokosc dlugosc wiersz

*wiersz

*wiersz x,y,

dlugosc wysokosc

x, y NULL

stos

elem nast

elem

elem

elem nast

nast

nast

wezel

Obiekt typu stos zawiera wskaźnik poczatek wskazujący na dynamiczny obiekt typu wezel zawierający dwa wskaźniki: elem wskazujący na obiekty z danymi, pochodzące z rodziny praprzodka klasy abstrakcyjnej abstr oraz drugi wskaźnik nast wskazujący na kolejny obiekt typu wezel. Obiekty z danymi pochodzą z rodziny obiektów zastosowanej w przykładach 12.1 i 12.2.

W bieżącym przykładzie zastosowano jedynie inną strukturę do przechowania tych samych obiektów - dynamiczną rekurencyjną strukturę danych typu stos.

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

(13)

#include "nram7_2.h"

#include "stos8_1.h"

...

void wyswietl(punkt*);

void wyswietl(abstr*);

void wyswietl(float, char * kom);

void main()

{ { n_ramka *n_r1, *n_r2;

ramka* r1,*r2;

napis* n1,*n2;

punkt* p1,*p2;

stos Stos;

abstr* p;

n_r1 = new n_ramka(36,10,19,8,"napis w ramce_1",0x3A);

Stos.wstaw(n_r1);

n_r2 = new n_ramka(54,8,19,5,"napis w ramce_2",0x1B);

Stos.wstaw(n_r2);

r1 = new ramka(50,12,10,8);

Stos.wstaw(r1);

r2 = new ramka(60,9,10,5);

Stos.wstaw(r2);

n1 = new napis(50,21,"napis1");

Stos.wstaw(n1);

n2 = new napis(63,18,"napis2");

Stos.wstaw(n2);

p1 = new punkt(12,13);

Stos.wstaw(p1);

p2 = new punkt(12,8);

Stos.wstaw(p2);

/*sposób odwołania do metod wirtualnych p_dlugosc klas ramka i punkt w celu odczytu dwóch pól o tej samej nazwie dlugosc dziedziczonych przez obiekt typu n_ramka od klasy ramka i napis - przy takim odwołaniu kompilator ustala

adres metod wirtualnych podczas kompilacji; */

cout << n_r1->napis::p_dlugosc()<<' ';

cout << n_r1->ramka::p_dlugosc()<<' ';

/*sposób odwołania do dwóch pól dlugosc dziedziczonych od klas ramka i punkt w celu odczytu ich wartości - możliwy przy dostępie public do składowych*/

cout<<n_r1->napis::dlugosc<<' ';

cout<<n_r1->ramka::dlugosc<<" \n";

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

(14)

/*1. W metodzie wirtualnej wyswietl, czystej w klasie abstr, przedefiniowanej i dziedziczonej od klasy punkt oraz w niezależnej funkcji wyswietl dostęp do jednej z dwóch metod wirtualnych p_dlugosc, jakie posiada aktualny obiekt klasy n_ramka wynika z kolejności umieszczenia klas bazowych w liście

dziedziczenia w klasie n_ramka */

/*2. Metoda stosu elementach typu abstr i parametrem abstr; posiadającego funkcję niezależną o nagłówku void(*)(abstr*) np. wyswietl(abstr*)

Stos.Dla _kazdego(wyswietl); //dzięki polimorfizmowi klasy abstrakcyjnej while (!Stos.pusty())

{

p=Stos.usun();

--(*p);--(*p); //dzięki polimorfizmowi klasy abstrakcyjnej p->wyswietl(„\nmetoda”); //dzięki polimorfizmowi klasy abstrakcyjnej wyswietl((punkt*)p); //dzięki polimorfizmowi klasy wirtualnej punkt

wyswietl(((punkt*)p)->odleglosc(*n_r1),"");

}

Stos.wstaw(n_r1); Stos.wstaw(n_r2);

Stos.wstaw(r1); Stos.wstaw(r2);

Stos.wstaw(n1); Stos.wstaw(n2);

Stos.wstaw(p1); Stos.wstaw(p2);

Stos.Dla_kazdego(wyswietl);

/* dzięki polimorfizmowi klasy abstrakcyjnej wywołanie destruktora stosu - usuwanie elementów stosu, pochodnych klasy abstr, dzięki jej wirtualnemu destruktorowi, przedefiniowanemu w klasach pochodnych*/

} }...

/* uniwersalna funkcja do wyświetlania pól całej rodziny obiektów: punkt, ramka, napis oraz n_ramka dzięki:

 przekazywaniu obiektów przez wskaźnik

 zastosowaniu polimorfizmu, czyli wywoływaniu metod wirtualnych: p_dlugosc, p_wiersz, p_wysokosc, p_atrybuty */

void wyswietl(punkt* p)

{cout<<"Atrybuty: " << p->p_atrybuty();

cout<<" Wiersz: " << p->p_wiersz();

cout<<" Dlugosc, Wysokosc: "<<p->p_dlugosc()<<" "<<p->p_wysokosc()<<"

";

cout << " Wspolrzedne: " << p->odcieta() << " "<< p->rzedna();

p->rysuj();.... }

void wyswietl(abstr* p) //funkcja do wyświetlania stosu elementów typu abstr*

{ --(*p);

p->wyswietl("");}

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

(15)

#include "abstr7_2.h" //zawartość pliku nagłówkowego stos8_1.h

#include <alloc.h>

class stos { struct wezel { abstr *elem;

wezel* nast;

wezel (abstr *x, wezel*y) {elem= x; nast= y;}

};

typedef wezel* polaczenie;

polaczenie poczatek;

public:

stos(int = NULL) {poczatek = NULL;}

~stos();

int pusty() {return poczatek==NULL;}

void wstaw(abstr *x)

{if (coreleft() >= sizeof(wezel))

poczatek = new wezel (x, poczatek);}

abstr* usun()

{if (!poczatek) return NULL;

abstr* v = poczatek->elem; polaczenie pom = poczatek->nast;

delete poczatek; poczatek=pom; return v;}

//uniwersalna metoda wykonująca dowolną funkcję o nagłówku void(*)(abstr*) na //elementach stosu

void Dla_kazdego(void (*p) (abstr*));

};

stos::~stos()

{ polaczenie pom= poczatek;

while (poczatek)

{ pom= poczatek->nast;

delete poczatek->elem;

delete poczatek;

poczatek= pom;}}

void stos::Dla_kazdego(void (*p)(abstr*)) { polaczenie pom= poczatek;

while(pom)

{ p(pom->elem);

pom= pom->nast;}}

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

Cytaty

Powiązane dokumenty

Zanim zaczniesz oglądać film, przygotuj zeszyt i coś do pisania Pamiętaj, że możesz zatrzymać film w każdej chwili i zrobić notatkę, oraz rozwiązać

Osoby, które w ostatni wtorek (19.05.2020), z różnych przyczyn nie napisały kartkówki, mogą ją napisać dzisiaj.

 istnieje mo˙zliwo´s´c rzutowania wska´znika(referencji) do klasy pochodnej na wska´znik (referencj ˛e) do klasy bazowej;.  istnieje mo˙zliwo´s´c tworzenia obiektu klasy bazowej

 Zmienna wskaźnikowa mająca typ pewnej klasy bazowej może wskazywać obiekty tej klasy oraz klas pochodnych - a zatem jest polimorficzna..  Zmienne niewskaźnikowe nie

– zdumiał się Janek, który przeprowadził się do ich miasteczka jakiś czas temu i nie znał wszystkich ekscytujących historii, krążących po okolicy.. – Nie słyszałeś o

-zna ogólne zasady działania urządzeń domowych (np. latarki, odkurzacza, zegara), posługuje się nimi, nie psując ich, -zna zagrożenia wynikające z niewłaściwego używania

• wyjaśnia, czym zajmują się różne dziedziny nauk biologicznych,

Pojawi się zatem mechanizm polimorfizmu - czyli metoda Rysuj, w zależności od obiektu, na którymjest wykonywana,.. sporządzi inny