Plik klasy. h deklaracje klas KLASY DLA PRZYKŁADÓW Z POLIMORFIZMEM enum dim r1 = 1, r2, r3; class figura public: static int const maxliczbafigur; = 100; static int liczbafigur; dim rn; rodzaj przestrzeni int n; liczba wierzchołków int kr; liczba krawędzi int dimxy; rozmiar tablicy wierzcholkow double* xy; wskaźnik do tablicy wierzcholkow int opislng; długość opisu (z uwzgl. \0) char* opis; opis figury figura(dim = r1, int = 1, int = 0, double* = NULL, char* = NULL); virtual ~figura() liczbafigur--; cout << "To ja - destruktor klasy figura" << endl; Funkcja wirtualna ma w całej hierarchi klas tę samo składnię, tzn. nazwę, liczbę, kolejność i typ parametrów oraz ten sam typ zwracany
; virtual double pole() = 0; void piszfigura(); konstruktor nie może być wirtualny, ale można utworzyć funkcje składowe spełniające tę samą rolę virtual figura* konstr_domn() = 0; virtual figura* konstr_kopi() = 0; class trojkat : public figura public: trojkat(double* = NULL, char* = "domniemany trojkat"); virtual ~trojkat(); wszystkie ponizsze funkcje MUSZA!!!! być zdefiniowane, gdyż w przeciwnym przypadku klasa dziedziczy je z klasy figura i staje się abstrakcyjna (w klasie figura są one czysto wirtualne) double virtual pole(); virtual figura* konstr_domn() return new trojkat(); virtual figura* konstr_kopi() return new trojkat(*this); ;
class czworokat : public figura public: czworokat(double* = NULL, char* = "domniemany czworokat"); virtual ~czworokat(); double virtual pole(); virtual figura* konstr_domn() return new czworokat(); virtual figura* konstr_kopi() return new czworokat(*this); ; Plik figura.cpp definicje metod #include "stdafx.h" using namespace std; KLASA FIGURA int const figura::maxliczbafigur = 100; inicjalizacja już została dokonana podczas deklaracji klasy dla składników statycznych jest to możliwe jeśli posiadają przydomek const int figura::liczbafigur = 0;
figura::figura(dim rn_, int n_, int kr_, double* xy_, char* str): rn(rn_), n(n_), kr(kr_), dimxy(rn_*n_) double *wxy, *wxy_; liczbafigur++; xy = new double[dimxy]; wxy = xy; if (xy_ == NULL) for(int i=0; i<dimxy; ++i, ++wxy) *wxy = 0.; else wxy_ = xy_; for(int i=0; i<dimxy; ++i, ++wxy, ++wxy_) *wxy = *wxy_; opislng = strlen(str) + 1; opis = new char[opislng]; strcpy(opis, str); cout << "Klasa figura - wskaznik this: " << this << endl; cout << "Klasa figura - pole: " << pole() << endl; double figura::pole() funkcja czysto wirtualna, a jednak może zostać wykonana gdy mimo wszystko nastąpi wczesne wiązanie i polimorfizm nie zadziała
cout << "Nieokreslona figura - brak pola" << endl; return -1.; void figura::piszfigura() cout << endl; cout << " Nazwa: " << opis << endl; cout << " Przestrzen: " << rn << endl; cout << " Liczba wezlow: " << n << endl; cout << " Liczba bokow: " << kr << endl; cout << " Pole powierzchni: " << pole() << endl; cout << "Wspolrzedne wezlow: " << endl; double *wxy = xy+1; for (int i=0; i<n; ++i, wxy+=2) cout << " (" << *(wxy-1) << ", " << *wxy << ") " << endl; KLASA TROJKAT trojkat::trojkat(double* xy_, char* str) : figura(r2, 3, 3, xy_, str) cout << "Klasa trojkat - wskaznik this: " << this << endl;
trojkat::~trojkat() cout << "Kasuje " << this->opis << endl; delete [] xy; delete [] opis; liczbafigur--; double poletrojk(double *xy) return 0.5*fabs(xy[2]*xy[5] + xy[1]*xy[4] + xy[0]*xy[3] - xy[2]*xy[1] - xy[4]*xy[3] + xy[5]*xy[0]); virtual double trojkat::pole() w definicji funkcji virtualnej już nie podaje się słowa virtual double trojkat::pole() return poletrojk(xy); KLASA CZWOROKAT czworokat::czworokat(double* xy_, char* str) : figura(r2, 4, 4, xy_, str) cout << "Klasa czworokat - wskaznik this: " << this << endl;
czworokat::~czworokat() cout << "Kasuje " << this->opis << endl; delete [] xy; delete [] opis; liczbafigur--; double czworokat::pole() int dlxy = rn*(n+1); double *nxy = new double[dlxy]; for (int i = 0; i < rn*n; i++) *(nxy+i) = *(xy+i); dopisanie współrzędnych pierwszego wierzchołka czworokąta na końcu (po ostatnim) *(nxy+dlxy-2) = *nxy; *(nxy+dlxy-1) = *(nxy+1); 1-szy trojkat - wierzchołki 1, 2, 3 2-gi trojkat - wierzchołki 3, 4, 5 = 1 double p = poletrojk(nxy) + poletrojk(nxy+4); delete [] nxy; return p;
Plik Polimorfizm - funkcja main #include "stdafx.h" using namespace std; double pole(figura& ob) return ob.pole(); int main(array<system::string ^> ^args) utworzenie obiektu klasy figura jest niemożliwe klasa figura jest klasą abstrakcyjną ze względu na istnienie funkcji czysto wirtualnych np. double pole() = 0 figura xxx; - błąd!!!! WCZESNE WIĄZANIE trojkat a; a.piszfigura();
double t1[6] = 0., 0., 1., 0., 0., 1.; trojkat b(t1, "moj trojkat"); b.piszfigura(); double t2[8] = 0., 0., 1., 0., 2., 2., 0., 1.; czworokat c(t2, "moj czworokat"); c.piszfigura(); PÓŹNE WIĄZANIE Wskaźnik do obiektu klasy figura cout << endl << "Wskaznik do obiektow typu figura: " << endl; figura *wskfig; wskfig = &b; cout << "Pole figury " << wskfig->opis << " wynosi " << wskfig->pole() << endl; wskfig = &c; cout << "Pole figury " << wskfig->opis << " wynosi " << wskfig->pole() << endl; Referencja do obiektu klasy figura cout << endl << "Referencja do obiektow typu figura: " << endl; cout << "Pole figury " << b.opis << " wynosi " << pole(b) << endl; cout << "Pole figury " << c.opis << " wynosi " << pole(c) << endl; WCZESNE WIĄZANIE - polimorfizm nie działa
Wywołanie na rzecz obiektu cout << endl << "Wywolanie na rzecz obiektu: " << endl; cout << "Pole figury " << c.opis << " wynosi " << c.pole() << endl; Zastosowanie kwalifikatora zakresu cout << endl << "Zastosowanie kwalifikatora zakresu: " << endl; cout << "Pole figury " << wskfig->figura::opis << " wynosi " << wskfig- >figura::pole() << endl; Wywołanie konstruktora i destruktora klasy podstawowej jeśli w ich wnętrzu znajduje się wywołanie funkcji wirtualnej, to i tak zostanie wywołana jej wersja właściwa dla klasy podstawowej, choć wskaźnik this będzie się odnosił do klasy pochodnej) Konstruktor nie może być wirtualny Poniżej wywołanie funkcji będących namiastkami konstruktorów figura *wskzewzoru = wskfig->konstr_kopi(); cout << endl << "Funkcja zastepujaca konstruktor kopiujacy: " << endl; cout << "Pole figury " << wskzewzoru->opis << " wynosi " << wskzewzoru->pole() << endl; figura *wskfignowy = wskfig->konstr_domn(); cout << endl << "Funkcja zastepujaca konstruktor domniemany: " << endl; cout << "Pole figury " << wskfignowy->opis << " wynosi " << wskfignowy->pole() << endl;
cout << endl << " Liczba obiektow typu figura: " << wskfig->liczbafigur << endl; system("pause"); return 0;