Programowanie obiektowe C++



Podobne dokumenty
Języki programowania

Programowanie obiektowe C++

Podstawy Programowania Obiektowego

Wykład 8: klasy cz. 4

Laboratorium nr 12. Temat: Struktury, klasy. Zakres laboratorium:

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

Wykład 5: Klasy cz. 3

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

TEMAT : KLASY DZIEDZICZENIE

Programowanie obiektowe C++

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

dr inż. Jarosław Forenc

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Programowanie obiektowe C++

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Język C++ Różnice między C a C++

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Instrukcja do pracowni specjalistycznej z przedmiotu. Obiektowe programowanie aplikacji

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Wykład 1. Program przedmiotu. Programowanie (język C++) Literatura. Program przedmiotu c.d.:

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Programowanie 2. Język C++. Wykład 3.

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Zaawansowane programowanie w języku C++ Klasy w C++

Programowanie obiektowe C++

Instytut Mechaniki i Inżynierii Obliczeniowej Wydział Mechaniczny Technologiczny Politechnika Śląska

PARADYGMATY PROGRAMOWANIA Wykład 2

Szablony funkcji i szablony klas

PARADYGMATY PROGRAMOWANIA Wykład 3

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Wstęp do Programowania 2

Do czego służą klasy?

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

Rozdział 4 KLASY, OBIEKTY, METODY

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

Wykład 4: Klasy i Metody

Język C++ wykład VII. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VII. dr Jarosław Mederski. Spis.

Programowanie Obiektowe i C++

Politechnika Krakowska im. Tadeusza Kościuszki. Karta przedmiotu. obowiązuje w roku akademickim 2012/2013. Przedmioty kierunkowe

Materiały do zajęć VII

Programowanie obiektowe

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM

Politechnika Krakowska im. Tadeusza Kościuszki. Karta przedmiotu. obowiązuje studentów rozpoczynających studia w roku akademickim 2012/2013

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

KARTA PRZEDMIOTU. 1. Informacje ogólne. 2. Ogólna charakterystyka przedmiotu. Programowanie I C6

Wprowadzenie do szablonów szablony funkcji

Wstęp do programowania obiektowego. Wykład 2

Języki i paradygmaty programowania

Wprowadzenie do szablonów szablony funkcji

Dziedziczenie. Ogólna postać dziedziczenia klas:

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Języki i techniki programowania Ćwiczenia 2

PARADYGMATY PROGRAMOWANIA Wykład 4

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Programowanie, część I

Podstawy Programowania Obiektowego

KARTA PRZEDMIOTU. 1. Informacje ogólne. 2. Ogólna charakterystyka przedmiotu. Programowanie II C16

Zaawansowane programowanie w C++ (PCP)

Programowanie obiektowe w C++ Wykład 12

Szablony klas, zastosowanie szablonów w programach

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

Programowanie obiektowe

C++ Przeładowanie operatorów i wzorce w klasach

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Laboratorium 1. Wprowadzenie, środowisko programistyczne, pierwsze programy

Język ludzki kod maszynowy

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 12

Różne właściwości. Różne właściwości. Różne właściwości. C++ - klasy. C++ - klasy C++ - KLASY

Język C++ Programowanie obiektowe

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

Przypomnienie o klasach i obiektach

Programowanie komputerowe. Zajęcia 7

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Referencje do zmiennych i obiektów

Wykład V. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Enkapsulacja, dziedziczenie, polimorfizm

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

Definiowanie własnych klas

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Technologie obiektowe

Podstawy algorytmiki i programowania - wykład 4 C-struktury

Podstawy programowania. Wykład: 12. Struktury, unie, pola bitowe. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Języki i paradygmaty programowania Wykład 2. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/18

Dokumentacja do API Javy.

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

Transkrypt:

Programowanie obiektowe C++ Programowanie zorientowane obiektowo Wykład 1 Witold Dyrka witold.dyrka@pwr.wroc.pl 10/10/2011

Prawa autorskie itp. Wiele slajdów do tego wykładu powstało w oparciu o: slajdy Bjarne Stroustrupa do kursu Foundations of Engineering II (C++) prowadzonego w Texas A&M University http://www.stroustrup.com/programming przykładowe programy Jerzego Grębosza do książki Symfonia C++ Standard http://www.ifj.edu.pl/~grebosz/symfonia_c++_std_p.html Dziękuję dr inż. lek. med. Marcinowi Masalskiemu za udostępnienie materiałów do wykładu w roku ak. 2010/11

Program wykładów 0. Bezpieczeństwo typów. Kontener vector. Obsługa błędów (26/09/2011) 1. Abstrakcja i enkapsulacja: klasy i struktury. Typ wyliczeniowy (10/10/2011) 2. Polimorfizm: przeładowanie funkcji i operatorów (24/10/2011) 3. Zarządzanie pamięcią: konstruktory, destruktory. Konwersje (21/11/2011) 4. Dziedziczenie (05/11/2011) 5. Programowanie uogólnione: szablony (19/12/2011) 6. Projektowanie programów orientowanych obiektowo (02/01/2012) 7. Kolokwium zaliczeniowe (16/01/2012)

Program laboratorium Techniki programowania orientowanego obiektowo w języku C++ Enkapsulacja i polimorfizm (lista 1) Zarządzanie pamięcią (lista 2) Dziedziczenie i abstrakcja (lista 3) Programowanie uogólnione (lista 4?) Obsługa błędów i odrobaczanie programu Korzystanie z biblioteki standardowej

Materiały Literatura Bjarne Stroustrup. Programowanie: Teoria i praktyka z wykorzystaniem C++. Helion (2010) Jerzy Grębosz. Symfonia C++ standard. Edition 2000 (2008) Dowolny podręcznik programowania zorientowanego obiektowo w języku C++ w standardzie ISO 98 Środowisko programistyczne Microsoft Visual C++ (rekomendowane) Dowolne środowisko korzystające z GCC

Warunki zaliczenia Kolokwium zaliczeniowe 16/01/2012 w czasie wykładu jedno kolokwium poprawkowe zaliczenie od >50% Uwaga! jeśli ktoś ma braki z programowania zapraszam na wykład pt. Języki programowania w środę o 18.55 do sali 1.30/C-13

Zasady Nie toleruję plagiatów dot. programów na laboratorium Nie toleruję ściągania dot. kolokwium i sprawdzianów na laboratorium Zachęcam do korzystania z konsultacji ze mną: PT 10-11, pok. 118A/D-1 pomiędzy sobą

Plan na dziś Klasy Implementacja i interfejs Konstruktory Funkcje składowe Składowe stałe Składowe statyczne Typ wyliczeniowy

Klasy Klasa bezpośrednio reprezentuje pojęcie w programie Jeśli o czymś można myśleć jako o oddzielnym bycie, to prawdopodobnie może to być klasą lub obiektem klasy Np. wektor, macierz, strumień wejściowy, łańcuch znakowy, szybka transformata Fouriera, kontroler zaworu, ramię robota, sterownik urządzenia, obraz na ekranie, okno dialogowe, wykres, okno, odczyt temperatur, zegar Klasa jest typem zdefiniowanym przez użytkownika, który określa jak tworzyć i używać obiekty tego typu Klasy po raz pierwszy wprowadzono w języku Simula67

Klasa, obiekt, zmienna class Pralka { // ta klasa nazywa się Pralka // Ciało klasy //... Pralka czerwona; int numer; Pralka *wskaznik; // definicja zmiennej czerwona typu Pralka // powstaje nowy obiekt, który otrzymuje nazwę czerwona // definicja zmiennej numer typu int // powstaje nowy obiekt, który otrzymuje nazwę numer // definicja wskaznika na typ Pralka Pralka &ruda = czerwona; // definicja referencji ruda do zmiennej czerwona Słowniczek: Klasa typ danych użytkownika Obiekt miejsce w pamięci przechowujące dane określonego typu Zmienna nazwany obiekt

Dane składowe klasy class Pralka { public: // ta klasa nazywa się Pralka // int nr_programu; // dane składowe (przechowują informacje) float temperatura_prania; string model; // czerwona.model = Frania ; // dostęp do danej składowej model zmiennej czerwona wskaznik = &czerwona; // ustawienie wskaznika na zmiennej czerwona wskaznik->model = Frania ; ruda.model = Frania ; // dostęp przez wskaźnik // dostęp przez referencję

Funkcje składowe klasy (metody) class Pralka { // ta klasa nazywa się Pralka public: int pierz(int program); // funkcje składowe (robią coś z danymi składowymi) void wiruj(int minuty); int nr_programu; // dane składowe (przechowują informacje) float temperatura_prania; string model; float krochmalenie(void); // znowu funkcja składowa int x = czerwona.pierz(1); int y = ruda.pierz(2); // wywołanie funkcji składowej pierz() dla czerwona // wywołanie funkcji składowej pierz() dla referencji ruda wskaznik = &czerwona; int z = wskaznik->pierz(3); // wywołanie funkcji składowej pierz() dla wskaznika

Definiowanie funkcji składowych wewnątrz ciała funkcji inline class osoba { public: string nazwisko; int wiek; // Definicje funkcji składowych: ==================================== void zapamietaj(const string &napis, int lata) { nazwisko = napis; wiek = lata; } // ------------------------------------------------------------------------------------------------------------- void wypisz() { cout << "\t" << nazwisko << ", lat: " << wiek << endl; } Kiedy? - Tylko krótkie funkcje, których ciało zajmuje do 2 linijek. - Kompilator (jeśli zechce) potraktuje je jako funkcje w linii, czyli inline

Definiowanie funkcji składowych na zewnątrz ciała funkcji class osoba { public: string nazwisko; int wiek; // Deklaracje funkcji składowych: ================================ void zapamietaj(const string &napis, int lata); void wypisz(); // Definicje funkcji składowych: ==================================== void osoba::zapamietaj(const string &napis, int lata) { nazwisko = napis; wiek = lata; } // ------------------------------------------------------------------------------------------------------------- void osoba::wypisz() { cout << "\t" << nazwisko << ", lat: " << wiek << endl; }

Inicjowanie obiektu typu użytkownika konstruktor Tworząc własny typ danych potrzebujemy określić sposób inicjowania obiektów tego typu: służy do tego konstruktor Konstruktor zawsze nazywa się tak samo jak jego klasa class osoba { public: string nazwisko; int wiek; // Deklaracje konstruktorów: =================================== osoba(const string &napis, int lata) : nazwisko(napis), wiek(lata) { osoba(int lata) : nazwisko("nn"), wiek(lata) { // Deklaracje funkcji składowych: ================================ void zapamietaj(const string &napis, int lata); void wypisz();

Interfejs i implementacja klasy class X { // klasa o nazwie X public: // funkcje // typy // publiczne składowe klasy interfejs użytkownika // (dostępne dla wszystkich) // dane (najczęściej lepiej, żeby były prywatne) private: // funkcje // typy // dane // priwatne składowe klasy szczegóły implementacyjne // (dostępne tylko dla składowych klasy)

Klasy i struktury Klasy mogą mieć dwie bliźniacze formy: class i struct Składowe klasy są domyślnie prywatne, czyli zapis: class X { int mf(); // oznacza tyle co: class X { private: int mf(); // Więc: X x; // zmienna x typu X int y = x.mf(); // błąd kompilacji: mf jest prywatna (niedostępna)

Klasy i struktury (2) Klasy mogą mieć dwie bliźniacze formy: class i struct Składowe struktury są domyślnie publiczne, czyli zapis: struct X { int m; // oznacza tyle co: class X { public: int m; // Rodzi się pytanie po co ukrywać składowe?

Po co komu prywatne składowe? Aby stworzyć przejrzysty interfejs klasy Dane i zagmatwane funkcje można ukryć Aby kontrolować niezmienniki Dzięki ograniczonemu zbiorowi funkcji z dostępem Aby ułatwić debugowanie Zawężenie grona podejrzanych Aby umożliwić zmianę reprezentacji (danych składowych) Wystarczy zmienić ograniczony zbiór funkcji W przypadku składowej publicznej nie można nigdy wiedzieć, kto ją używa

Struktura tylko dane (jak w języku C) // najprostsza wersja Date (tylko dane) struct Date { int y,m,d; // rok, miesiąc, dzień my_birthday: y m d Date: Date my_birthday; // zmienna typu Date (obiekt) my_birthday.y = 12; my_birthday.m = 30; my_birthday.d = 1950; // Ups! (nie ma dnia 1950 w miesiącu 30) // Błąd nie został zgłoszony, ale dalej w programie // będziemy mieli problemy

Struktura tylko dane (jak w języku C) podejście 2 // prosta wersja Date (dodaliśmy kilka funkcji pomocnicznych) struct Date { int y,m,d; // rok, miesiąc, dzień my_birthday: y Date: m d Date my_birthday; // zmienna typu Date (obiekt) // funkcje pomocnicze: void init_day(date& dd, int y, int m, int d); void add_day(date&, int n); // // sprawdź poprawność daty i inicjalizuj // zwiększ obiekt Date o n dni init_day(my_birthday, 12, 30, 1950); // błąd czasu wykonania: // nie ma dnia 1950 w miesiącu 30 Świetnie, ale nie ma gwarancji, że użytkownik struktury użyje funkcji init_day() po utworzeniu zmiennej typu Date.

Struktura w stylu C++ my_birthday: y Date: m // prosta Date // gwarantuje inicjalizację przy użyciu konstruktora d // zapewnia pewną wygodę notacyjną struct Date { int y,m,d; // rok, miesiąc, dzień Date(int y, int m, int d); // konstruktor: sprawdza poprawność daty i inicjuje void add_day(int n); // zwiększa datę o n dni 1950 // Date my_birthday; // błąd: my_birthday nie zainicjowane (I dobrze!) Date my_birthday(12, 30, 1950); // ups! Błąd czasu wykonania Date my_day(1950, 12, 30); // ok my_day.add_day(2); // 1 stycznia 1951 my_day.m = 14; // grrrhh! (teraz my_day jest niepoprawną datą) Świetnie, poprawna inicjacja jest zagwarantowana. Niestety, publiczny dostęp do danych składowych Date grozi zepsuciem daty 12 30

Klasa (z kontrolą dostępu) m 12 // prosta Date (z kontrolą dostępu) class Date { d 30 int y,m,d; // rok, miesiąc, dzień public: Date(int y, int m, int d); // konstruktor: sprawdza poprawność daty i inicjuje // funkcje dostępowe: void add_day(int n); // zwiększa datę o n dni int month() { return m; } int day() { return d; } int year() { return y; } // Date my_birthday(1950, 12, 30); cout << my_birthday.month() << endl; my_birthday.m = 14; my_birthday: y Date: 1950 // ok // możemy odczytać miesiąc // błąd: składowa Date::m jest prywatna

Niezmienniki Pojęcie poprawnej daty jest szczególnym przypadkiem pojęcia poprawnej wartości Zasada: zagwarantować poprawne wartości dla projektowanego typu (poprawny stan obiektu) Inaczej musielibyśmy cały czas sprawdzać poprawność danych lub liczyć, że zrobi to użytkownik klasy Regułę opisującą poprawną wartość nazywa się niezmiennikiem W przypadku daty jest to wyjątkowo trudne (28 luty, rok przestępny itd.) Jeśli nie można znaleźć dobrego niezmiennika pracujesz na samych czystych danych Użyj struktury Pierwszą opcją jest jednak zawsze szukanie niezmienników!

Prosty konstruktor klasy // prosta Date (niektórzy wolą interfejs klasy na początku dlaczego?) d 30 class Date { public: Date(int y, int m, int d); // konstruktor: sprawdza poprawność daty i inicjuje void add_day(int n); int month(); // private: int y,m,d; // rok, miesiąc, dzień Date::Date(int yy, int mm, int dd) :y(yy), m(mm), d(dd) { /* */ // zwiększa datę o n dni my_birthday: y Date: m // definicja konstruktora klasy // inicjacja składowych 1950 12 void Date::add_day(int n) { /* */ // definicja funkcji

Konstruktor z kontrolą poprawności // prosta Date (co zrobimy z nieprawidłową datą) class Date { public: class Invalid { // użyta jako rakieta sygnalizacyjna // przy obsłudze wyjątków Date(int y, int m, int d); // sprawdza poprawność daty i inicjuje // private: int y,m,d; // rok, miesiąc, dzień bool check(int y, int m, int d); // czy (y,m,d) jest poprawną datą? Date:: Date(int yy, int mm, int dd) : y(yy), m(mm), d(dd) // inicjuje dane składowe { if (!check(y,m,d)) throw Invalid(); // sprawdza poprawność daty }

Wyliczenia Wyliczenie enum (ang. enumaration) jest typem użytkownika określającym zestaw wartości (elementy wyliczenia) Na przykład: enum Month { jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec Month m = feb; m = 7; // błąd: nie można przypisać int do Month int n = m; // ok: możemy dostać wartość liczbową Month Month mm = Month(7); // konwersja typu int na Month (nie sprawdzana)

Zastosowanie wyliczeń Prosta lista stałych enum { red, green int a = red; enum { red, blue, purple // enum { } nie definiuje zakresu // red jest dostępne tutaj // błąd: red jest już zdefiniowany Typ z listą stałych enum Day { sun, mon, tue, /* */ // domyślnie: sun==0, mon==1, tue==2 enum Color { red=100, green=1, blue=10, /* */ Day m1 = sun; Day m2 = red; Day m3 = 7; int i = m1; // błąd: red nie jest wartością Day // błąd: 7 nie jest wartością Day // ok: element wyliczenia jest konwertowany do // swojej wartości, i==0

Klasa z wyliczeniem // prosta Date (używa typu Month) class Date { public: my_birthday: y enum Month { jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec Date(int y, Month m, int d); // sprawdza poprawność daty i inicjuje // private: int y; // rok Month m; int d; // dzień Date: m d 1950 12 30 Date my_birthday(1950, 30, Date::dec); Date my_birthday(1950, Date::dec, 30); // błąd: 2. argument nie jest miesiącem // ok enum pomaga kontrolować poprawność // zwróć też uwagę na zakres: Date::dec

Składniki stałe klasy (const) class Date { public: // int day() const { return d; } void add_day(int n); // // stały składnik: nie może modyfikować // nie-stały składnik: może modyfikować Date d(2000, Date::jan, 20); const Date cd(2001, Date::feb, 21); // zmienna d typu Date // stała cd typu Date cout << d.day() << " " << cd.day() << endl; // ok d.add_day(1); // ok cd.add_day(1); // błąd: cd jest const // Tylko stałe funkcje składowe są dopuszczane // do działania na stałych obiektach klasy

Składniki stałe klasy (2) // Date d(2004, Date::jan, 7); const Date d2(2004, Date::feb, 28); d2 = d; // błąd: d2 jest const d2.add(1); // błąd: d2 jest const d = d2; // w porządku d.add(1); // w porządku // zmienna // stała d2.f(); // Taka operacja powinna zostać wykonana wtedy i tylko wtedy, gdy // funkcja składowa f() nie modyfikuje danych składowych obiektu d2 // Jak to zapewnić? (zakładając, że tego właśnie chcemy)

Składniki stałe klasy (3) // Rozróżnij pomiędzy funkcjami, które mogą modyfikować obiekty // I tymi, które nie mogą zwanymi stałymi funkcjami składowymi class Date { public: // int day() const; // pobierz dzień (w zasadzie jego kopię) // void add_day(int n); // przesuń datę o n do przodu // const Date dx(2008, Month::nov, 4); int d = dx.day(); // w porządku dx.add_day(4); // błąd: nie można modyfikować stałych danych

Dobry interfejs klasy Minimalny Tak mały jak to możliwe Kompletny I nie mniejszy Bezpieczny dla typów (ang. type-safe) Uwaga na kolejność argumentów Poprawnie określać stałe składniki klasy (ang. const-correct)

Minimalny zestaw składowych Najbardziej podstawowe operacje Konstruktor domyślny (domyślnie: nie robi nic lub brak domyślnego konstruktora jeśli zadeklarowano inny konstruktor Konstruktor kopiujący (domyślnie: kopiuje składowe) Operator przypisania (domyślnie: kopiuje składowe) Destruktor (domyślnie: nie robi nic) Na przykład Date d; Date d2 = d; d = d2; // błąd: brak domyślnego konstruktora (zadeklarowaliśmy inny!) // ok: inicjacja kopią (kopiuje elementy domyślne) // ok: przypisanie kopii (kopiuje elementy domyślne)

Interfejs klasy i funkcje pomocnicze Chcemy minimalny interfejs klasy (zbiór funkcji pomocnicznych), bo to: Ułatwia zrozumienie klasy Upraszcza debugowanie Upraszcza pielęgnację Potrzebujemy funkcji pomocniczych, operujących na obiektach klasy, ale zdefiniowanych poza klasą, np. == (równość),!= (nierówność) next_weekday(), next_sunday()

Funkcje pomocnicze Date next_sunday(const Date& d) { // ma dostęp do obiektu d poprzez d.day(), d.month(), oraz d.year() // tworzy nowy obiekt typu Date który zwraca } Date next_weekday(const Date& d) { /* */ } bool operator==(const Date& a, const Date& b) { return a.year()==b.year() && a.month()==b.month() && a.day()==b.day(); } bool operator!=(const Date& a, const Date& b) { return!(a==b); }

Funkcje zaprzyjaźnione Czasem warto dać funkcji pomocniczej dostęp do prywatnych składowych klasy np. zamiast tworzenia funkcji day(), month(), year(). class Date { public: //.. friend void print(date &d) const; // funkcja zaprzyjaźniona wyświetlająca datę private: int y,m,d; void print(date &d) const { cout << "Today is " << d.d << "/" << d.m << "/" << d.y << endl; } Date dx; print(&dx);

Składniki statyczne...czyli składniki wspólne dla wszystkich obiektów danej klasy ( zmienne globalna dla klasy ) Zastosowania: Do porozumiewania się pomiędzy obiektami klasy (jako flaga) Jako istniejących licznik obiektów danej klasy Gdy pewna cecha będzie się zmieniać jednocześnie dla wszystkich obiektów danej klasy Dostęp do wejścia/wyjścia (np. pliku) - wspólnego dla wszystkim obiektów klasy

Składniki statyczne przykład class piorko { enum tak_czy_nie { nie, tak } ; int poz_x, poz_y ; static int zezwolenie ; string kolor ; public : // funkcje ------------------------------------------------------------ void jazda(int x, int y); static void czy_mozna(tak_czy_nie odp) { dana statyczna tu: prywatna funkcja statyczna zezwolenie = odp ; // składnik statyczny zezwolenie // poz_x = 5 ; // błąd! bo składnik zwykły poz_x // Funkcja statyczna może odwoływać się // tylko do składników statycznych klasy } piorko(const string kol) : kolor(kol), poz_x(0), poz_y(0) {

Składniki statyczne przykład (kont.) void piorko::jazda(int x, int y) { cout << "Tu "<< kolor << " piorko : " ; if(zezwolenie) { poz_x = x ; poz_y = y ; cout << "Jade do punktu ("<< poz_x << ", " << poz_y << ")\n" ; } else { cout << " Nie wolno mi jechac!!!!!!!!!!!!! \n" ; } } int piorko::zezwolenie = piorko::nie; // Daną statyczną definujemy i inicjujemy poza ciałem klasy // Wyjątek: stała statyczna int main() { piorko::czy_mozna(piorko::tak) ; } // Funkcję statyczną możemy wywołać mimo, że // nie został jeszcze utworzony obiekt klasy piorko piorko czarne("smoliste"), zielone("zieloniutkie") ; czarne.jazda(0, 0) ; zielone.jazda(1100, 1100) ; piorko::czy_mozna(piorko::nie) ; czarne.jazda(10, 10) ; zielone.jazda(1020, 1020) ; zielone.czy_mozna(piorko::tak); czarne.jazda(50, 50) ; zielone.jazda(1060, 1060) ; // zabraniamy ruchu piórkom // zezwalamy w taki sposób

Dziś najważniejsze było to, że... Klasa reprezentuje pojęcie Obiekt jest ucieleśnieniem tej klasy Zmienna jest nazwanym obiektem Oddzielamy interfejs od implementacji (enkapsulacja) Zasady tworzenia dobrego interfejsu: minimalny, ale kompletny, zawiera funkcje zaprzyjaźnione bezpieczny dla typów, określa składowe stałe

A za 2 tygodnie... Polimorfizm: przeładowanie funkcji i operatorów