of 42 /42
Programowanie obiektowe C++ Programowanie zorientowane obiektowo Wykład 1 Witold Dyrka [email protected] 10/10/2011

Programowanie obiektowe C++ - ibp.pwr.wroc.pl obiektowe C++/POCPP... · wykorzystaniem C++. Helion (2010) Jerzy Grębosz. Symfonia C++ standard. Edition 2000 (2008) Dowolny podręcznik

  • Author
    vutuyen

  • View
    216

  • Download
    0

Embed Size (px)

Text of Programowanie obiektowe C++ - ibp.pwr.wroc.pl obiektowe C++/POCPP... · wykorzystaniem C++. Helion...

Programowanie obiektowe C++Programowanie zorientowane obiektowo

Wykad 1

Witold [email protected]

10/10/2011

mailto:[email protected]

Prawa autorskie itp.

Wiele slajdw do tego wykadu powstao w oparciu o: slajdy Bjarne Stroustrupa

do kursu Foundations of Engineering II (C++) prowadzonego w Texas A&M Universityhttp://www.stroustrup.com/Programming

przykadowe programy Jerzego Grbosza do ksiki Symfonia C++ Standardhttp://www.ifj.edu.pl/~grebosz/symfonia_c++_std_p.html

Dzikuj dr in. lek. med. Marcinowi Masalskiemu za udostpnienie materiaw do wykadu w roku ak. 2010/11

http://www.stroustrup.com/Programminghttp://www.ifj.edu.pl/~grebosz/symfonia_c++_std_p.html

Program wykadw0. Bezpieczestwo typw. Kontener vector. Obsuga bdw (26/09/2011)

1. Abstrakcja i enkapsulacja: klasy i struktury. Typ wyliczeniowy (10/10/2011)

2. Polimorfizm: przeadowanie funkcji i operatorw (24/10/2011)

3. Zarzdzanie pamici: konstruktory, destruktory. Konwersje (21/11/2011)

4. Dziedziczenie (05/11/2011)

5. Programowanie uoglnione: szablony (19/12/2011)

6. Projektowanie programw orientowanych obiektowo (02/01/2012)

7. Kolokwium zaliczeniowe (16/01/2012)

Program laboratorium Techniki programowania orientowanego obiektowo

w jzyku C++ Enkapsulacja i polimorfizm (lista 1) Zarzdzanie pamici (lista 2) Dziedziczenie i abstrakcja (lista 3) Programowanie uoglnione (lista 4?)

Obsuga bdw i odrobaczanie programu Korzystanie z biblioteki standardowej

Materiay

Literatura Bjarne Stroustrup. Programowanie: Teoria i praktyka z

wykorzystaniem C++. Helion (2010) Jerzy Grbosz. Symfonia C++ standard. Edition 2000 (2008) Dowolny podrcznik programowania zorientowanego obiektowo

w jzyku C++ w standardzie ISO 98

rodowisko programistyczne Microsoft Visual C++ (rekomendowane) Dowolne rodowisko korzystajce z GCC

Warunki zaliczenia Kolokwium zaliczeniowe

16/01/2012 w czasie wykadu jedno kolokwium poprawkowe

zaliczenie od >50%

Uwaga! jeli kto ma braki z programowania zapraszam na wykad pt. Jzyki programowania

w rod o 18.55 do sali 1.30/C-13

Zasady Nie toleruj plagiatw

dot. programw na laboratorium

Nie toleruj cigania dot. kolokwium i sprawdzianw na laboratorium

Zachcam do korzystania z konsultacji ze mn: PT 10-11, pok. 118A/D-1 pomidzy sob

Plan na dzi Klasy

Implementacja i interfejs Konstruktory Funkcje skadowe Skadowe stae Skadowe statyczne

Typ wyliczeniowy

Klasy Klasa bezporednio reprezentuje pojcie w programie

Jeli o czym mona myle jako o oddzielnym bycie, to prawdopodobnie moe to by klas lub obiektem klasy

Np. wektor, macierz, strumie wejciowy, acuch znakowy, szybka transformata Fouriera, kontroler zaworu, rami robota, sterownik urzdzenia, obraz na ekranie, okno dialogowe, wykres, okno, odczyt temperatur, zegar

Klasa jest typem zdefiniowanym przez uytkownika, ktry okrela jak tworzy i uywa obiekty tego typu

Klasy po raz pierwszy wprowadzono w jzyku Simula67

Klasa, obiekt, zmiennaclass Pralka { // ta klasa nazywa si Pralka

// Ciao klasy// ...

};

Pralka czerwona; // definicja zmiennej czerwona typu Pralka// powstaje nowy obiekt, ktry otrzymuje nazw czerwona

int numer; // definicja zmiennej numer typu int// powstaje nowy obiekt, ktry otrzymuje nazw numer

Pralka *wskaznik; // definicja wskaznika na typ Pralka

Pralka &ruda = czerwona; // definicja referencji ruda do zmiennej czerwona

Sowniczek:

Klasa typ danych uytkownika

Obiekt miejsce w pamici przechowujce dane okrelonego typu

Zmienna nazwany obiekt

Dane skadowe klasyclass Pralka { // ta klasa nazywa si Pralkapublic:

//

int nr_programu; // dane skadowe (przechowuj informacje)float temperatura_prania;string model;

//

};

czerwona.model = Frania; // dostp do danej skadowej model zmiennej czerwona

wskaznik = &czerwona; // ustawienie wskaznika na zmiennej czerwona

wskaznik->model = Frania; // dostp przez wskanik

ruda.model = Frania; // dostp przez referencj

Funkcje skadowe klasy (metody)class Pralka { // ta klasa nazywa si Pralkapublic:

int pierz(int program); // funkcje skadowe (robi co z danymi skadowymi)void wiruj(int minuty);

int nr_programu; // dane skadowe (przechowuj informacje)float temperatura_prania;string model;

float krochmalenie(void); // znowu funkcja skadowa};

int x = czerwona.pierz(1); // wywoanie funkcji skadowej pierz() dla czerwona

int y = ruda.pierz(2); // wywoanie funkcji skadowej pierz() dla referencji ruda

wskaznik = &czerwona;

int z = wskaznik->pierz(3); // wywoanie funkcji skadowej pierz() dla wskaznika

Definiowanie funkcji skadowychwewntrz ciaa funkcji inline

class osoba {

public:

string nazwisko; int wiek;

// Definicje funkcji skadowych: ====================================void zapamietaj(const string &napis, int lata) {

nazwisko = napis;wiek = lata;

} // -------------------------------------------------------------------------------------------------------------

void wypisz() {cout

Definiowanie funkcji skadowych na zewntrz ciaa funkcji

class osoba {

public:

string nazwisko; int wiek;

// Deklaracje funkcji skadowych: ================================void zapamietaj(const string &napis, int lata);void wypisz();

};

// Definicje funkcji skadowych: ====================================void osoba::zapamietaj(const string &napis, int lata) {

nazwisko = napis;wiek = lata;

} // -------------------------------------------------------------------------------------------------------------void osoba::wypisz() {

cout

Inicjowanie obiektu typu uytkownika konstruktor

Tworzc wasny typ danych potrzebujemy okreli sposb inicjowania obiektw tego typu: suy do tego konstruktor

Konstruktor zawsze nazywa si tak samo jak jego klasaclass osoba {

public:

string nazwisko; int wiek;

// Deklaracje konstruktorw: =================================== osoba(const string &napis, int lata) : nazwisko(napis), wiek(lata) { }; osoba(int lata) : nazwisko("NN"), wiek(lata) { };

// Deklaracje funkcji skadowych: ================================void zapamietaj(const string &napis, int lata);void wypisz();

};

class X { // klasa o nazwie Xpublic: // publiczne skadowe klasy interfejs uytkownika

// (dostpne dla wszystkich)// funkcje// typy// dane (najczciej lepiej, eby byy prywatne)

private: // priwatne skadowe klasy szczegy implementacyjne// (dostpne tylko dla skadowych klasy)

// funkcje// typy// dane

};

Interfejs i implementacja klasy

Klasy i strukturyKlasy mog mie dwie bliniacze formy: class i struct

Skadowe klasy s domylnie prywatne, czyli zapis:

class X { int mf();

// };

oznacza tyle co:

class X {private:

int mf();//

}; Wic:

X x; // zmienna x typu Xint y = x.mf(); // bd kompilacji: mf jest prywatna (niedostpna)

Klasy i struktury (2)Klasy mog mie dwie bliniacze formy: class i struct

Skadowe struktury s domylnie publiczne, czyli zapis:

struct X { int m;

// };

oznacza tyle co:

class X {public:

int m;//

};

Rodzi si pytanie po co ukrywa skadowe?

Po co komu prywatne skadowe? Aby stworzy przejrzysty interfejs klasy

Dane i zagmatwane funkcje mona ukry Aby kontrolowa niezmienniki

Dziki ograniczonemu zbiorowi funkcji z dostpem Aby uatwi debugowanie

Zawenie grona podejrzanych Aby umoliwi zmian reprezentacji (danych skadowych)

Wystarczy zmieni ograniczony zbir funkcji W przypadku skadowej publicznej nie mona nigdy

wiedzie, kto j uywa

// najprostsza wersja Date (tylko dane) struct Date {

int y,m,d; // rok, miesic, dzie};

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 miesicu 30)

// Bd nie zosta zgoszony, ale dalej w programie// bdziemy mieli problemy

Date:my_birthday: y

m

d

Struktura tylko dane(jak w jzyku C)

// prosta wersja Date (dodalimy kilka funkcji pomocnicznych)struct Date {

int y,m,d; // rok, miesic, dzie};

Date my_birthday; // zmienna typu Date (obiekt)

// funkcje pomocnicze:

void init_day(Date& dd, int y, int m, int d); // sprawd poprawno daty i inicjalizujvoid add_day(Date&, int n); // zwiksz obiekt Date o n dni//

init_day(my_birthday, 12, 30, 1950); // bd czasu wykonania: // nie ma dnia 1950 w miesicu 30

wietnie, ale nie ma gwarancji, e uytkownik struktury uyje funkcji init_day() po utworzeniu zmiennej typu Date.

Date:my_birthday: y

m

d

Struktura tylko dane(jak w jzyku C) podejcie 2

// prosta Date // gwarantuje inicjalizacj przy uyciu konstruktora// zapewnia pewn wygod notacyjnstruct Date {

int y,m,d; // rok, miesic, dzieDate(int y, int m, int d); // konstruktor: sprawdza poprawno daty i inicjujevoid add_day(int n); // zwiksza dat o n dni

};

// Date my_birthday; // bd: my_birthday nie zainicjowane (I dobrze!)Date my_birthday(12, 30, 1950); // ups! Bd czasu wykonaniaDate my_day(1950, 12, 30); // okmy_day.add_day(2); // 1 stycznia 1951my_day.m = 14; // grrrhh! (teraz my_day jest niepoprawn dat)

wietnie, poprawna inicjacja jest zagwarantowana. Niestety, publiczny dostp do danych skadowych Date grozi zepsuciem daty

1950

30

12

Date:my_birthday: y

m

d

Struktura w stylu C++

// prosta Date (z kontrol dostpu)class Date {

int y,m,d; // rok, miesic, dziepublic:

Date(int y, int m, int d); // konstruktor: sprawdza poprawno daty i inicjuje

// funkcje dostpowe:void add_day(int n); // zwiksza dat o n dniint month() { return m; } int day() { return d; }int year() { return y; }

};

// Date my_birthday(1950, 12, 30); // okcout

Niezmienniki Pojcie poprawnej daty jest szczeglnym przypadkiem pojcia

poprawnej wartoci Zasada: zagwarantowa poprawne wartoci dla

projektowanego typu (poprawny stan obiektu) Inaczej musielibymy cay czas sprawdza poprawno danych

lub liczy, e zrobi to uytkownik klasy Regu opisujc poprawn warto nazywa si

niezmiennikiem W przypadku daty jest to wyjtkowo trudne (28 luty, rok przestpny itd.)

Jeli nie mona znale dobrego niezmiennika pracujesz na samych czystych danych Uyj struktury Pierwsz opcj jest jednak zawsze szukanie niezmiennikw!

// prosta Date (niektrzy wol interfejs klasy na pocztku dlaczego?)class Date {public:

Date(int y, int m, int d); // konstruktor: sprawdza poprawno daty i inicjujevoid add_day(int n); // zwiksza dat o n dniint month();//

private:int y,m,d; // rok, miesic, dzie

};

Date::Date(int yy, int mm, int dd) // definicja konstruktora klasy:y(yy), m(mm), d(dd) { /* */ }; // inicjacja skadowych

void Date::add_day(int n) { /* */ }; // definicja funkcji

1950

30

12

Date:my_birthday: y

m

d

Prosty konstruktor klasy

// prosta Date (co zrobimy z nieprawidow dat)class Date {public:

class Invalid { }; // uyta jako rakieta sygnalizacyjna// przy obsudze wyjtkw

Date(int y, int m, int d); // sprawdza poprawno daty i inicjuje//

private:int y,m,d; // rok, miesic, dziebool 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 skadowe

{if (!check(y,m,d)) throw Invalid(); // sprawdza poprawno daty

}

Konstruktor z kontrol poprawnoci

Wyliczenia Wyliczenie enum (ang. enumaration) jest typem uytkownika

okrelajcym zestaw wartoci (elementy wyliczenia)

Na przykad:enum Month {

jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};

Month m = feb;m = 7; // bd: nie mona przypisa int do Monthint n = m; // ok: moemy dosta warto liczbow MonthMonth mm = Month(7); // konwersja typu int na Month (nie sprawdzana)

Zastosowanie wylicze Prosta lista staych

enum { red, green }; // enum { } nie definiuje zakresuint a = red; // red jest dostpne tutajenum { red, blue, purple }; // bd: red jest ju zdefiniowany

Typ z list staychenum Day { sun, mon, tue, /* */ }; // domylnie: sun==0, mon==1, tue==2enum Color { red=100, green=1, blue=10, /* */ }; Day m1 = sun;Day m2 = red; // bd: red nie jest wartoci DayDay m3 = 7; // bd: 7 nie jest wartoci Dayint i = m1; // ok: element wyliczenia jest konwertowany do

// swojej wartoci, i==0

// prosta Date (uywa typu Month)class Date {public:

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; // rokMonth m;int d; // dzie

};

Date my_birthday(1950, 30, Date::dec); // bd: 2. argument nie jest miesicemDate my_birthday(1950, Date::dec, 30); // ok enum pomaga kontrolowa poprawno

// zwr te uwag na zakres: Date::dec

1950

30

12

Date:my_birthday: y

m

d

Klasa z wyliczeniem

class Date {public:

// int day() const { return d; } // stay skadnik: nie moe modyfikowavoid add_day(int n); // nie-stay skadnik: moe modyfikowa//

};

Date d(2000, Date::jan, 20); // zmienna d typu Dateconst Date cd(2001, Date::feb, 21); // staa cd typu Date

cout

//Date d(2004, Date::jan, 7); // zmiennaconst Date d2(2004, Date::feb, 28); // staad2 = d; // bd: d2 jest constd2.add(1); // bd: d2 jest constd = d2; // w porzdkud.add(1); // w porzdku

d2.f(); // Taka operacja powinna zosta wykonana wtedy i tylko wtedy, gdy// funkcja skadowa f() nie modyfikuje danych skadowych obiektu d2// Jak to zapewni? (zakadajc, e tego wanie chcemy)

Skadniki stae klasy (2)

// Rozrnij pomidzy funkcjami, ktre mog modyfikowa obiekty// I tymi, ktre nie mog zwanymi staymi funkcjami skadowymiclass 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 porzdkudx.add_day(4); // bd: nie mona modyfikowa staych danych

Skadniki stae klasy (3)

Dobry interfejs klasy Minimalny

Tak may jak to moliwe Kompletny

I nie mniejszy Bezpieczny dla typw (ang. type-safe)

Uwaga na kolejno argumentw Poprawnie okrela stae skadniki klasy

(ang. const-correct)

Minimalny zestaw skadowych Najbardziej podstawowe operacje

Konstruktor domylny (domylnie: nie robi nic lub brak domylnego konstruktora jeli zadeklarowano inny konstruktor

Konstruktor kopiujcy (domylnie: kopiuje skadowe) Operator przypisania (domylnie: kopiuje skadowe) Destruktor (domylnie: nie robi nic)

Na przykadDate d; // bd: brak domylnego konstruktora (zadeklarowalimy inny!)

Date d2 = d; // ok: inicjacja kopi (kopiuje elementy domylne)

d = d2; // ok: przypisanie kopii (kopiuje elementy domylne)

Interfejs klasy i funkcje pomocnicze Chcemy minimalny interfejs klasy (zbir funkcji

pomocnicznych), bo to: Uatwia zrozumienie klasy Upraszcza debugowanie Upraszcza pielgnacj

Potrzebujemy funkcji pomocniczych, operujcych na obiektach klasy, ale zdefiniowanych poza klas, np. == (rwno) , != (nierwno) next_weekday(), next_Sunday()

Date next_Sunday(const Date& d){

// ma dostp do obiektu d poprzez d.day(), d.month(), oraz d.year()// tworzy nowy obiekt typu Date ktry 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 pomocnicze

Funkcje zaprzyjanione Czasem warto da funkcji pomocniczej dostp do prywatnych skadowych klasy

np. zamiast tworzenia funkcji day(), month(), year().

class Date {

public:// ..friend void print(Date &d) const; // funkcja zaprzyjaniona wywietlajca dat

private:int y,m,d;

};

void print(Date &d) const {cout

Skadniki statyczne...czyli skadniki wsplne dla wszystkich obiektw danej klasy (zmienne globalna dla klasy) Zastosowania:

Do porozumiewania si pomidzy obiektami klasy (jako flaga) Jako istniejcych licznik obiektw danej klasy Gdy pewna cecha bdzie si zmienia jednoczenie dla

wszystkich obiektw danej klasy Dostp do wejcia/wyjcia (np. pliku) - wsplnego dla

wszystkim obiektw klasy

Skadniki statyczne przykad

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){ zezwolenie = odp ; // skadnik statyczny zezwolenie // poz_x = 5 ; // bd ! bo skadnik zwyky poz_x

// Funkcja statyczna moe odwoywa si// tylko do skadnikw statycznych klasy

}piorko(const string kol) : kolor(kol), poz_x(0), poz_y(0) { };

};

dana statyczna

tu: prywatna

funkcja statyczn

a

Skadniki statyczne przykad (kont.)void piorko::jazda(int x , int y) {

cout

Dzi najwaniejsze byo to, e...

Klasa reprezentuje pojcie Obiekt jest ucielenieniem tej klasy

Zmienna jest nazwanym obiektem

Oddzielamy interfejs od implementacji (enkapsulacja)

Zasady tworzenia dobrego interfejsu: minimalny, ale kompletny, zawiera funkcje zaprzyjanione bezpieczny dla typw, okrela skadowe stae

A za 2 tygodnie...

Polimorfizm:przeadowanie funkcji i operatorw