Laboratorium nr 12 Temat: Polimorfizm oraz funkcje wirtualne.. 1. Koncepcja polimorfizmu oraz funkcji wirtualnych w C++ Polimorfizm: oznacza istnienie kilku wersji funkcji lub operatorów o tej samej nazwie. W C++ mamy dwie formy polimorfizmu: statyczny (wykonywany w czasie kompilacji) oraz dynamiczny. Polimorfizm statyczny odnosi się do przeciążania funkcji oraz operatorów natomiast polimorfizm dynamiczny jest realizowany przy wykorzystaniu funkcji wirtualnych. Różnica pomiędzy polimorfizmem statycznym a dynamicznym polega na tym, że w statycznym C++ wybiera odpowiednią wersję przeciążonej funkcji podczas kompilacji. W polimorfizmie dynamicznym C++ znajduje odpowiednia wersję przeciążonej funkcji na podstawie wskaznika do obiektu. Funkcje wirtualne: ich koncepcja jest podobne do przeciążania funkcji, z tym, że w przypadku funkcji wirtualnych możemy zastąpić ich definicję w klasie bazowej, nowa definicją w klasie pochodnej. W tym celu należy w klasie bazowej należy poprzedzić definicję funkcji słowem virtual. class klasa { public: virtual typ funkcja (argumenty); } class nowa:public klasa{ public: int funkcja (argumenty); } Uwaga: w C++ istnieje także koncepcja czystych funkcji wirtualnych, to znaczy takich, dla których występuje jedynie deklaracji w klasie bazowej zakończona znakiem =0 . W klasach pochodnych należy wówczas zamienić czystą funkcję wirtualna jej deklaracją. Klasa, która zawiera czyste funkcje wirtualne nazywa się klasą abstrakcyjną i nie może istnieć żaden obiekt tej klasy & virtual typ funkcja (argumenty)=0; ! czysta funkcja wirtualna # include # include # include using namespace std; class macierz { public: int x,y; virtual int wyswietl(void)=0; }; class itg:public macierz { public: int *tab; int wyswietl (void); int wprowadz (int w); itg(int n, int m); ~itg(); }; class flt:public macierz { public: float *tab; int wyswietl (void); int wprowadz (float w); flt(int n, int m); ~flt(); }; int itg::wyswietl(void){ cout << "\nMacierz: Integer" << endl; for (int i=0; i for (int j=0; j cout <<"\n"; }; }; int itg::wprowadz (int w) { for(int i=0;i for(int j=0;j *(tab+y*i+j)= w; return 0; }; itg::itg(int n, int m){ x=n; y=m; tab=new int[n*m]; for (int i=0; i for (int j=0; j *(tab+y*i+j)=0; } itg::~itg(){ delete[] tab; }; int flt::wyswietl (void){ cout << "\nMacierz: Float" << endl; for (int i=0; i for (int j=0; j<< "\t"; cout <<"\n"; }; }; int flt::wprowadz (float w) { for(int i=0;i for(int j=0;j *(tab+y*i+j)=w; return 0; }; flt::flt(int n, int m){ x=n; y=m; tab=new float[n*m]; for (int i=0; i for (int j=0; j *(tab+y*i+j)=0; } flt::~flt(){ delete[] tab; }; int main() { class itg A(3,3); class flt B(3,3); A.wprowadz(1); A.wyswietl(); B.wprowadz(1.1); B.wyswietl(); system("PAUSE"); delete &A; delete &B; return 0; } 2. Zadanie: Zmodyfikuj powyższy program tak, aby umożliwiał deklaracje szeregu macierzy o dowolnych wymiarach i typach (integer, float, char, itp.) oraz podstawowe działania na macierzach (dodawanie, mnożenie, transpozycja, itp.) z wykorzystaniem funkcji wirtualnych. Uwaga: " Program powinien składać się z oddzielnych plików, tzn. pliku głównego oraz plików zdefiniowanych klas, itp. " Program powinien posiadać szereg zabezpieczeń, np. sprawdzanie czy wybrane macierzy mają odpowiednie typy i wymiary oraz czy istnieje przestrzeń na utworzenie kolejnej macierzy, itp. Program powinien posiadać krótkie menu wyboru, np.: 1. Utwórz macierz: integer, float, char 2. Wyświetl macierz 3. Wypełnij macierz dane losowe 4. Dodaj macierze 5. Pomnóż macierze 6. itp. 7. Koniec