• Nie Znaleziono Wyników

Wykład 5 Dziedziczenie jednobazowe c.d.

N/A
N/A
Protected

Academic year: 2021

Share "Wykład 5 Dziedziczenie jednobazowe c.d."

Copied!
1
0
0

Pełen tekst

(1)

Wykład 5

Dziedziczenie jednobazowe c.d.

1. Dziedziczenie metod i operatorów bez przedefiniowania (pokrywania) 2. Dziedziczenie metod i operatorów z przedefiniowaniem

3. Obiekty z dynamicznymi polami typu dwuwymiarowa tablica elementów typu int-

3.1. przeciążanie operatora << na rzecz dowolnej klasy oraz operatora wywołania funkcji ()

3.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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 1

(2)

1. Dziedziczenie metod i operatorów bez przedefiniowania (pokrywania)

Przykład 5.1

W klasie bazowej punkt i klasie pochodnej kolo (przykład 4.2) wykonać:

a) konstruktory: zwykły i kopiujący za pomocą listy argumentów b) operator == jako funkcje zaprzyjaźniona w klasie punkt

c) operator != jako metoda klasy punkt.

Operatory te powinny porównywać pola x i y w dwóch obiektach pochodzących z dowolnej klasy (punkt lub kolo).

W przypadku operatorów z b) i c) argument typu kolo jest poddany naturalnej konwersji do klasy punkt.

Stałe typu int są poddane konwersji konstruktorowej do klasy punkt w przypadku operatora b) zawsze, bo:

operator == (obiekt_klasy_punkt, obiekt_klasy_punkt), a w przypadku operatora c) tylko dla prawych argumentów, gdyż:

obiekt_klasy_punkt.operator != (obiekt_klasy_punkt):

b)wyswietl(6==punkt2,”6==punkt2”); 

operator== (6, punkt2) oraz

wyswietl(8==kolo2,”8==kolo2”);  operator == (8, kolo2) 

poprawne!

c)wyswietl(6!=punkt2,"6!=punkt2 jest rowne "); 6.operator != (punkt2) oraz

wyswietl(8!=kolo2,"8!=kolo2 jest rowne "); 8.operator != (kolo2);  błędy!

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 2

(3)

...

#include "kolo5_2.h"

#include "punkt5_2.h"

void wyswietl(kolo&);

void wyswietl(punkt&);

void wyswietl(float);

void wyswietl(int, char *);

void main()

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

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

wyswietl(kolo1);

wyswietl(kolo2);

wyswietl(punkt1);

wyswietl(punkt2);

wyswietl(punkt1==punkt2, "\npunkt1==punkt2 jest rowne ");

wyswietl(kolo1==kolo2, "kolo1==kolo2 jest rowne ");

wyswietl(punkt1==kolo2, "punkt1==kolo2 jest rowne ");

wyswietl(6==punkt2, "6==punkt2 jest rowne ");

wyswietl(kolo2==8, "kolo2==8 jest rowne ");

wyswietl(punkt1==2, "punkt1==2 jest rowne ");

wyswietl(punkt1!=punkt2, "punkt1!=punkt2 jest rowne ");

wyswietl(kolo1!=kolo2, "kolo1!=kolo2 jest rowne ");

wyswietl(punkt1!=kolo2, "punkt1!=kolo2 jest rowne ");

// wyswietl(6!=punkt2, "6!=punkt2 jest rowne ");

// wyswietl(8!=kolo2," 8!=kolo2 jest rowne ");

wyswietl(punkt1!=2,"punkt1!=2 jest rowne ");

}

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 3

(4)

class punkt // plik nagłówkowy punkt5_2.h { static int ile_punktow;

float x,y;

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

punkt(punkt&);

~punkt();

void przesun (float, float);

float odleglosc(punkt&) const;

static int liczba_punktow();

static int info();

float& odcieta();

float& rzedna();

int operator!=(const punkt&);

friend int operator==(const punkt&, const punkt&);

};

#include "punkt5_2.h" //plik nagłówkowy kolo5_2.h class kolo:public punkt

{ static int ile_kol; //kolo posiada wszystkie pola klasy punkt oraz własne:

float promien; //ile_kol oraz promien public: kolo (float=0, float=0, float=0);

kolo(kolo&);

~kolo();

static int liczba_kol(); //dziedziczy wszystkie metody oprócz static int info(); //konstruktorów, destruktora oraz funkcji float& p_promien(); //zaprzyjaźnionej operator==

};

#include "punkt5_2.h" //plik punkt5_2.cpp z definicjami metod klasy punkt punkt::punkt(float xx, float yy) : x(xx),y(yy) { ile_punktow++; } punkt::punkt(punkt& p) : x(p.odcieta()), y(p.rzedna()) { ile_punktow++; }

float& punkt::odcieta() { return x;}

int punkt::operator!=(const punkt& p) { return !(*this==p); } int operator ==(const punkt &p1, const punkt &p2)

{ return p1.x==p2.x && p1.y==p2.y;} //...

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

#include "punkt5_2.h"

kolo::kolo(float xx, float yy, float rr): promien(rr), punkt(xx, yy) { ile_kol++; } kolo::kolo(kolo& p) : punkt(p), promien(p.p_promien()) { ile_kol++; } //...

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 4

(5)

2. Dziedziczenie metod i operatorów z przedefiniowaniem (pokrywaniem)

Przykład 5.2

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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 5

(6)

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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 6

(7)

3. Obiekty z dynamicznymi składowymi typu dwuwymiarowa tablica elementów typu int

3.1. przeciążanie operatora << na rzecz dowolnej klasy oraz operatora wywołania funkcji ()

Przykład 5.3

Program w przykładzie 5.3 wprowadza i wyświetla współrzędne wierzchołków wielokąta oraz rysuje wierzchołki w postaci znaków ¦ w miejscach o podanych współrzędnych.

Klasa figura jest wykonana w następujący sposób:

 tablica Figura jest dynamiczną tablicą o elementach typu int, traktowaną jako tablicę dwuwymiarową o liczbie wierszy max_w (liczba wierzchołków figury) oraz liczbie kolumn max_kol (liczba współrzędnych punktu). Pole ile przechowuje liczbę aktualnie wprowadzonych współrzędnych. Zastosowanie jednowymiarowej tablicy pozwala na elastyczny podział na dwa wymiary, gdzie wiersze reprezentują liczbę wierzchołków wielokąta, natomiast kolumny określają liczbę współrzędnych wierzchołków. W przykładzie max_kol= 2.

 konstruktor zwykły tworzący dynamiczną tablice Figura, konstruktor kopiujący tworzący dynamiczną tablicę Figura i kopiujący zawartość przekazywanego obiektu oraz destruktor usuwający tę tablicę

 metodę rysuj, wyświetlającą znak ¦ na ekranie w miejscu (x, y), wtedy gdy znajduje się w obrębie ekranu (1<= x <=80, 1 <=y<=25). Dane każdego wierzchołka pobiera z dynamicznej tablicy struktur Figura.

 metodę przesun, zmieniającą współrzędne x o dx i y o dy wybranego elementu - wierzchołka z tablicy Figura

 wykonano operator <<, gdzie lewy argument jest obiektem klasy figura, a prawym argument typu int (kolejne współrzędne). Wynikiem działania operatora, wykonanego jako metoda, jest referencja do lewego argumentu, czyli obiektu wywołującego metodę. Operator ten zastosowano do zapisu współrzędnych wierzchołków wielokąta do tablicy Figura.

 zamiast metod dostępu do współrzędnych np. odcieta(int) i rzedna(int) przeciążono operator wywołania funkcji operator()(int, int) jako metodę, zastępujący indeksowanie [][] w tablicy dwuwymiarowej, niemożliwy do przeciążenia w C++ (można przeciążać tylko operator [] dwuargumentowy, gdzie lewym argumentem jest obiekt, a prawym indeks - tabela, wykład 4) Operator wykorzystano do czytania współrzędnych wierzchołków wielokąta, umieszczonych w tablicy Figura.

Należy zabezpieczyć metody przed dostępem do elementów tablicy Figura poza jej ograniczającymi indeksami 0 <= indeks < max_w *max_kol.

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 7

(8)

//...

#include "fig4_4.h"

void wprowadz_punkty(figura&);

void wyswietl(const figura);

void main() {do

{ figura wielokat(5, 2);

wprowadz_punkty(wielokat);

wielokat.rysuj();

wyswietl(wielokat);

} while (getch() != 27); }

void wprowadz_punkty(figura& wielokat) { int ile_w = wielokat.podaj_wsp_x(), a;

int ile_kol = wielokat.podaj_wsp_y();

for (int i = 0; i < ile_w; i++) for int j = 0; j < ile_kol; j++)

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

wielokat << a; }}

void wyswietl(const figura wielokat) { int ile_w = wielokat.podaj_wsp_x();

int ile_kol = wielokat.podaj_wsp_y();

for (int i = 0; i < ile_w; i++) {for int j = 0; j < ile_kol; j++)

cout << setw(15) << "Wielokat[" << i << "," << j << "] " <<

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

cout<<'\n';}}

class figura //plik nagłówkowy fig. 4_4.h

{int max_w, max_kol, ile;

int* Figura;

int koniec(int, int) const;

public: figura (int = 1, int = 2);

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; } ;

#include "fig4_4.h" //plik z definicjami metod fig4_4.cpp ...

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 8

(9)

figura::figura (int xx, int yy) {

ile = 0;

max_w = xx;

max_kol = yy

Figura = new int [max_w*max_kol];

if (Figura==NULL) exit(1);

}

figura::figura(figura& p) {

ile = 0;

max_w = p.max_w;

max_kol = p.max_kol;

Figura = new int max_w*max_kol];

if (Figura==NULL) exit(1);

for (int i = 0; i < max_w; i++)

for (int j = 0; j < max_kol; j++)

*this << p(i, j); }} // Figura[i*max_kol+j] = p(i, j);

int figura::koniec(int ile_w, int ile_kol) const

{return ile_w >=0 && ile_w<max_w && ile_kol>=0 && ile_kol<max_kol; }

figura& figura::operator<<(int xx) { if (ile < max_w*max_kol) Figura[ile++] = xx;

return (*this); }

int figura::operator()(int ile_w, int ile_kol) const {if (koniec(ile_w, ile_kol))

return Figura[ile_w*max_kol + ile_kol];

return Figura[0]; }

Zofia Kruczkiewicz Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 9

(10)

3.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 5.4.

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 (przykład 5.3) 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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 10

(11)

#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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 11

(12)

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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 12

(13)

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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 13

(14)

#include "fig5_4.h" //plik fig5_4.cpp z definicjami metod klasy figura ... // metody zaprezentowane w przykładzie 5.3

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

ile = 0;

max_w = p.max_w;

max_kol = p.max_kol;

Figura = new int [max_wmax_kol];

if (Figura==NULL) exit(1);

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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 14

(15)

#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 Programowanie obiektowe, Wykład 5 Politechnika Wrocławska 15

Cytaty

Powiązane dokumenty

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

nie otwiera się na rzeczywistość, ponieważ w takiej strukturze jest to niemożliwe, zawsze będzie owa przemoc uwikłana w symbole, lecz jednak właśnie jej nadmiar, dostarczany

1) Badanie wiedzy intuicyjnej (Czy znają słowo funkcja? W jakich sytuacjach można je zastosować?). 3) Kontrprzykłady, przypadki szczególne (identyczność, funkcja stała) nadal

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

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

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

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