Wykład 9 Przykłady programów z wykorzystaniem klas - przykład funkcji operatorowych - obiektowa implementacja listy jednokierunkowej kopiowanie obiektów - klasa "latający napis" Pozycjonowanie w plikach we/wy 2014-06-20 09:37 PP2_W9 1
Przykład funkcji operatorowych program OperatoryOvLoad: // Przykład przeciążenia operatorów - funkcje operatorowe // Copyright by Tadeusz Jeleniewski 2014 // #include "stdafx.h" // Deklaracja klasy PUNKT, definicje metod i funkcji //operatorowych class PUNKT double x, y; // domyślnie private public: PUNKT(double _x=0, double _y=0): x(_x), y(_y) // konstruktor // funkcje zaprzyjaźnione bo sięgają z zewnątrz do składowych // prywatnych friend istream& operator>>(istream&, PUNKT&); friend ostream& operator<<(ostream&, PUNKT&); friend PUNKT& operator+(punkt&, PUNKT&); ; 2014-06-20 09:37 PP2_W9 2
// Definicje funkcji operatorowych istream& operator>>(istream& st, PUNKT& p) cout<<"wspolrzedne x, y: "; return st>>p.x>>p.y; // ostream& operator<<(ostream& st, PUNKT& p) return st<<"punkt o wspolrzednych: ["<<p.x<<", "<<p.y<<']'; // PUNKT& operator+(punkt& A, PUNKT& B) A.x = A.x + B.x; A.y = A.y + B.y; return A; // 2014-06-20 09:37 PP2_W9 3
int _tmain(int argc, _TCHAR* argv[]) int n, i; cout << "Rozmiar obiektu klasy PUNKT: " << sizeof (PUNKT) << endl; cout << "Podaj liczbe punktow: "; cin >> n; PUNKT *A = new PUNKT[n]; for (i=0;i<n;i++) cout << "Punkt "<<i+1<<" - "; cin >> *(A+i); // działa przeciążony operator >> for (i=0;i<n;i++) cout << *(A+i)<<endl; // działa przeciążony operator << if (n > 1) A[0] = A[0] + A[1]; // działa przeciążony operator + cout << *A << endl; A[0] = A[0] + A[1] + A[n-1]; cout << *A << endl; system ("PAUSE"); return 0; 2014-06-20 09:37 PP2_W9 4
2014-06-20 09:37 PP2_W9 5
Obiektowa implementacja listy jednokierunkowej kopiowanie obiektów // Przykład klasy lista, gdzie elementami listy są obiekty // oraz przykład kopiowania obiektu klasy LISTA na inny obiekt // tej samej klasy // Copyright by Tadeusz Jeleniewski, 2014 // #include "stdafx.h" #define sep "\n==============================================================\n" #define pusta "Lista pusta\n" // manipulatory własne class OSOBA // deklaracja klasy - jej obiekty są wierzchołkami listy public: int identyf; // skladowe klasy - publiczne char nazwisko[35], imie[30]; float wynagrodzenie; OSOBA* link; // wskaznik na nastepny obiekt // konstruktor domyślny ; 2014-06-20 09:37 PP2_W9 6
class LISTA private: // dane prywatne OSOBA* L; int ile; OSOBA* PobierzDane(void); // metody prywatne void PokazDane(OSOBA*); public: LISTA(void); // konstruktor klasy void WstawOstatni(void); // metody publiczne void PiszListe(void); ; //------------ Konstruktor klasy LISTA ------------------- LISTA::LISTA(void) L = NULL; ile = 0; 2014-06-20 09:37 PP2_W9 7
//------ Definicje metod skladowych ---------------- OSOBA* LISTA::PobierzDane(void) OSOBA *wskaznik = new OSOBA(); // tworzy i alokuje // obiekt OSOBA w pamięci wskaznik->identyf = ++ile; cout << "Podaj imie: "; cin >> wskaznik->imie; wskaznik->imie[0]=toupper(wskaznik->imie[0]); cout << "Nazwisko: "; cin >> wskaznik->nazwisko; wskaznik->nazwisko[0]=toupper(wskaznik->nazwisko[0]); cout << "Wynagrodzenie: "; cin >> wskaznik->wynagrodzenie; return wskaznik; 2014-06-20 09:37 PP2_W9 8
void LISTA::PokazDane(OSOBA* wskaznik) if (wskaznik==null) return; cout << "Identyfikator: " << wskaznik->identyf << endl; cout << " - Imie: cout << " - Nazwisko: " << wskaznik->imie << endl; " << wskaznik->nazwisko << endl; cout << " - Wynagrodzenie: " << fixed << setprecision(2) << setw(6) << wskaznik->wynagrodzenie << sep; 2014-06-20 09:37 PP2_W9 9
char Menu(void) char znak; cout << "Nacisnij:" << endl; cout << " 1 - aby dopisac na koniec listy," << endl; cout << " 2 - aby wyswietlic liste," << endl; cout << " 3 - aby skopiowac liste," << endl; cout << " 4 - aby wyswietlic kopie listy," << endl; cout << " 0 - aby zakonczyc prace." << endl; cin >> znak; cin.ignore(1); return znak; 2014-06-20 09:37 PP2_W9 10
int _tmain(int argc, _TCHAR* argv[]) bool Koniec = false; LISTA Q, K; do switch (Menu()) case '1' : Q.WstawOstatni(); break; case '2' : cout << "Lista Q = " << endl; Q.PiszListe(); break; case '3' : K = Q; //Operacja kopiowania obiektów - dozwolona break; case '4' : cout << "Lista K = " << endl; K.PiszListe(); break; default: Koniec = true; while (!Koniec); system("pause"); return 0; 2014-06-20 09:37 PP2_W9 11
2014-06-20 09:37 PP2_W9 12
2014-06-20 09:37 PP2_W9 13
2014-06-20 09:37 PP2_W9 14
// Program MVS_latajacy_napis - przykład definicji pewnej // klasy oraz użycia jej obiektów // Copyrigth by Tadeusz Jeleniewski 2014 #include "stdafx.h" // // defnicja funkcji gotoxy(int x, int y) - poza standardem + // dostepna w kompilatorach Borland // jej implementacja w MS Visual Studio void gotoxy(int x, int y) COORD c; // klasa COORD zdefiniowana w pliku nagłówkowym // Windows.h c.x = x - 1; c.y = y - 1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); 2014-06-20 09:37 PP2_W9 15
class TITLE // deklaracja klasy TITLE private: int x, y, l; // x, y - pozycja ekranowa, // l - długość łańcucha char z[40]; // z - łańcuch znaków do // wyświetlenia public: TITLE(int, int, char*); // konstruktor obiektu void Show(void); // pokazuje obiekt TITLE void Hide(void); // ukrywa obiekt void Move(int, int); // przesuwa obiekt na // ekranie ; // Konstruktor obiektu TITLE::TITLE(int _x, int _y, char* _z) x = _x; y = _y; strcpy(z, _z); l = strlen(z); Show(); 2014-06-20 09:37 PP2_W9 16
// Pozostałe metody void TITLE::Show(void) gotoxy(x, y); cprintf("%s", z); void TITLE::Hide(void) gotoxy(x, y); for (int i=0;i<l;i++) cprintf(" "); gotoxy(x, y); void TITLE::Move(int dx, int dy) Hide(); x+=dx; y+=dy; Show(); // przesuwa kurso do pozycji x, y // wyświetla napis // "zakrywa" napis 2014-06-20 09:37 PP2_W9 17
TITLE* p[2]; // tablica globalna na dwa wsk. obiektów TITLE // Funkcja główna int _tmain(int argc, _TCHAR* argv[]) char zn='t'; TITLE A(40,12,"Good afternoon"); p[0] = &A; while (tolower(zn=getch())!='q') switch (zn) case 't': case 'u': A.Move(0,-1); // 1 wiersz w górę break; case 'f': case 'l': A.Move(-1,0); // 1 kolumna w lewo break; case 'g': case 'r': A.Move(1,0); // 1 kolumna w prawo break; 2014-06-20 09:37 PP2_W9 18
case 'v': case 'd': A.Move(0,1); // 1 wiersz w dół break; case 'n': TITLE B(41,11, "What are you doing"); // nowy obiekt p[1] = &B; B.Move(0,0); // można też tak p[1]->move(0,0); break; system("cls"); // "czyści" ekran return 0; 2014-06-20 09:37 PP2_W9 19
2014-06-20 09:37 PP2_W9 20
2014-06-20 09:37 PP2_W9 21
Pozycjonowanie w plikach we/wy Termin plik sugeruje, że informacja jest tam umieszczona w określonej kolejności. Strumienie reprezentujące pliki są tak zdefiniowane, aby istniała możliwość czytania z nich lub pisania do nich danych (ciągu bajtów) od określonego miejsca lub w określone miejsce. Strumienie mają "wskaźniki" pozycji. Jeśli strumień jest wejściowy, to ma taki wskaźnik do czytania. Pokazuje nie bajt a miejsce pomiędzy dwoma bajtami - ten z lewej" to ostatnio przeczytany, a ten z prawej" będzie czytany jako następny. Strumień wyjściowy ma wskaźnik do pisania. Strumień, który może zapewniać i pisanie i czytanie - ma oba takie wskaźniki - są one niezależne od siebie. Można przecież w jednym miejscu pliku czytać i zapisywać coś w innym. 2014-06-20 09:37 PP2_W9 22
Wskaźnik czytania - wskaźnik get Jeśli otwieramy plik do czytania, to wskaźnik ten znajduje się na początku pliku. Plik tak jak nową książkę zaczyna się zwykle czytać od początku. Wskaźnik ten jednak można natychmiast przesunąć w wybrane miejsce. Wskaźnik pisania - wskaźnik put Jeśli otwieramy plik do dopisywania (tryb ios::app ) to wskaźnik ten pokazuje na koniec pliku. Dopisywać będziemy na końcu pliku. Wskaźniki do pokazywania wewnątrz plików są typu streampos Typ ten zdefiniowano w klasach istream oraz ostream. Najczęściej jest to po prostu typ long. Określa on numer czytanego lub pisanego bajtu W stosunku do takich wskaźników wykonuje się zwykle dwa rodzaje operacji: - ustalenie pozycji pokazywanej przez wskaźnik - ustawienie wskaźnika na żądaną pozycję. 2014-06-20 09:37 PP2_W9 23
Funkcje składowe informujące o pozycji wskaźników streampos tellg(); f. składowa klasy ifstream streampos tellp(); f. składowa klasy ofstream Przykład: ofstream strum("wiersz.tmp", ios::app); strum << "Przykład użycia funkcji tellp" << endl; cout << "Pozycja wskaźnika = " << (strum.tellp()); 2014-06-20 09:37 PP2_W9 24
Wybrane funkcje składowe do pozycjonowania wskaźników istream & seekg(streampos, seek_dir = ios::beg); ostream & seekp(streampos, seek_dir = ios::beg); lub prościej (nie zawsze): istream & seekg(long, seek_dir = ios::beg); ostream & seekp(long, seek_dir = ios::beg); pierwszy argument określa przesunięcie jako liczbę bajtów, drugi to kierunek przesunięcia domyślnie względem początku pliku. Typ wyliczeniowy enum seek_dir beg, cur, end ; zdefiniowano w klasie ios Przykład projekt Pozycja 2014-06-20 09:37 PP2_W9 25