+ All Categories
Home > Documents > Úvod do objektov ě orientovaného programování

Úvod do objektov ě orientovaného programování

Date post: 21-Mar-2016
Category:
Upload: lois
View: 47 times
Download: 3 times
Share this document with a friend
Description:
Úvod do objektov ě orientovaného programování. RNDr. Filip Zavoral, Ph.D. Katedra softwarového inženýrství MFF UK Malostransk é nám. 25, Praha 1 Filip.Zavoral @ mff.cuni.cz http ://ulita.ms.mff.cuni.cz/~zavoral/VSFS. Studijní povinnosti. Přednáška 1.5 hod (od 9 :00) - PowerPoint PPT Presentation
76
Úvod do objektově orientovaného programování RNDr. Filip Zavoral, Ph.D. Katedra softwarového inženýrství MFF UK Malostranské nám. 25, Praha 1 [email protected] http://ulita.ms.mff.cuni.cz/~zavoral/VSFS
Transcript
Page 1: Úvod do  objektov ě orientovaného programování

Úvod do objektově orientovaného programování

RNDr. Filip Zavoral, Ph.D.Katedra softwarového inženýrství MFF UK

Malostranské nám. 25, Praha 1

[email protected]://ulita.ms.mff.cuni.cz/~zavoral/VSFS

Page 2: Úvod do  objektov ě orientovaného programování

Studijní povinnostiPřednáška 1.5 hod (od 9:00)Cvičení 1.5 hod (do 11:30)Následné osobní konzultace (45 min ve studovně)

Klasifikovaný zápočet Příklady na cvičeních, 'domácí úkoly' Závěrečný test

Odladit krátký program v omezeném čase Podmínka účasti – úspěšně absolvovaný test z PJC (ZS)

Zápočtový program Libovolný prográmek, zůstává ze ZS, stačí C, nemusí být OOP Samostatně vypracovat během semestru

Page 3: Úvod do  objektov ě orientovaného programování

Literatura

Bjarne Stroustrup: The C++ Programming Language

Bruce Eckel: Myslíme v jazyku C++James O. Coplien:

Advanced C++ Programming Styles and IdiomsHerb Sutter: Exceptional C++Miroslav Virius: Pasti a propasti jazyka C++Miroslav Virius: Programování v C++

http://kmdec.fjfi.cvut.cz/~virius/liter/litCpp.htm

Page 4: Úvod do  objektov ě orientovaného programování

ZS (PJC) LS (OOP)

Obsah předmětu

C++

C

C++

C

Page 5: Úvod do  objektov ě orientovaného programování

Paradigmata programování, OOPObjekty, zapouzdření, dědičnostKonstruktory a destruktory, new a deletePozdní vazba, virtuální funkcePřetěžování funkcí, předefinování operátorůAbstraktní datové typyOO styly a idiomyVýjimky, šablony, knihovny, streams, STL, RTTI, ...

Obsah předmětu

Page 6: Úvod do  objektov ě orientovaného programování

Procedurální programování jakou akci mám provést vstup – výpočet (algoritmus) – výstup black box: procedura / funkce !! side effects, údržba

Modulární programování rozdělení problému na komponenty procedury pracují nad daty - rozhraní black box: modul

Paradigmata programování

Page 7: Úvod do  objektov ě orientovaného programování

Datová abstrakce vytvoření vlastního datového typu (abstract/user defined

d.t.) kompletní množina operací nad tímto typem black box: datový typ !! nelze rozumně rozšiřovat

Objektové programování dědičnost – obecné / konkrétní vlastnosti polymorfismus možnost pozdějších rozšíření

Paradigmata programování

Page 8: Úvod do  objektov ě orientovaného programování

Koncepční pohled objekt: entita reagující na vnější podněty třída: monžina stejně reagujících entit

Technický pohled objekt: struktura obsahující data a funkce, instance třídy

datové položky, metody; angl. members třída: typ objektu

Rozhraní – veřejné informace pro uživateleImplementace – (neveřejná) interní data a metody

Třídy a objekty

Page 9: Úvod do  objektov ě orientovaného programování

Zvíře v C++ - rozhraní

class zvire{private: int zaludek;

public: zvire() { zaludek = 1; };

int zije() { return zaludek>0; }; int jez( int jidlo); int vymesuj( int objem);};

definice třídyzvire.

hvnitřní stav

(privátní)

rozhraní(veřejné)

datová položkainline tělo

funkce

konstruktor(inicializace

)metod

y

inline tělo funkce

deklarace metody

Page 10: Úvod do  objektov ě orientovaného programování

Zvíře - implementace

int zvire::jez( int jidlo){ if( ! zije()) return 0; return zaludek += jidlo;}

int zvire::vymesuj( int objem){ if( (zaludek -= objem) <= 0) zaludek = 0; return zaludek;}

zvire.cpp

třída metody

:: operátor kvalifikac

eimplementac

e (tělo) metody

přístup k datům třídy

Page 11: Úvod do  objektov ě orientovaného programování

Zvíře - použití

#include ”zvire.h”

.....{ ..... zvire pytlik;

pytlik.jez(5); pytlik.vymesuj(3); if( ! pytlik.zije()) return –1; pytlik.vymesuj(4); if( ! pytlik.jez(1)) return –2; .....}

mujprogram.cpp

instance třídy = objekt

automaticky

konstruktor

import rozhraní

zaludek = 1

zaludek = 3

-2 0

Page 12: Úvod do  objektov ě orientovaného programování

Objekt - instance třídy

int zvire::jez( int jidlo){ if( ! zije()) return 0; return zaludek += jidlo;}

..... zvire pytlik, beruska;

pytlik.jez( 5); beruska.jez( 1);.....

dvě instance třídy

Metoda třídy - ke kterému objektu má

přistupovat?

zaludek

6

zaludek

2

pytlik:

beruska:

?

Page 13: Úvod do  objektov ě orientovaného programování

this

int jez( zvire* this, int jidlo){ if( ! zije( this)) return 0; return this->zaludek += jidlo;}

..... zvire pytlik, beruska;

jez( &pytlik, 5); jez( &beruska, 1);.....

Každá metoda dostane tajný

parametr this - ukazatel na objekt

zaludek

6

zaludek

2

pytlik:

beruska:

C-style řešení

this

Page 14: Úvod do  objektov ě orientovaného programování

Reference

int x = 1, y = 2;int *px;px = &x;*px = 3;

int &ry = y;ry = 4;

return *px + ry;

reference - pouze inicializacenelze měnit

3x: :px

4y: :ry

reference i ukazatele jsou reprezentovány

adresou

Page 15: Úvod do  objektov ě orientovaného programování

Reference jako parametry

swap( int& a, int& b){ int c = a; a = b; b = c;}

int x = 1, y = 2;swap( x, y);

skutečné parametryodkazy na proměnné

1x: :a

2y: :b

význam:zpřehlednění kódupřetěžování

operátorů !

Page 16: Úvod do  objektov ě orientovaného programování

Přetěžování funkcí

int pocitej( int x){ return x+1;}

int pocitej( int a, int b){ return 2*a + b;}

pocitej( 1); // int pocitej( int)pocitej( 1, 2); // int pocitej( int, int)

Funkce se stejným identifikátorem ale

různým počtem parametrů

Funkce je definována svým identifikátorem a počtem a typem parametrů

Funkce se stejným identifikátorem ale

různým počtem parametrů

Správná funkce podle počtu a typů skutečných

parametrů

Page 17: Úvod do  objektov ě orientovaného programování

Konstruktoryclass zvire{private: int zaludek;

public: zvire() { zaludek = 1; }; zvire( int zal) { zaludek = zal; }; zvire( zvire& vzor) { zaludek = vzor.zaludek; };};

zvire beruska;zvire pytlik( 20);zvire beberuska( beruska);zvire tlustoch = pytlik;

implicitní konstruktor

copy (kopírovací) konstruktor

X(X&)

různé zápisy copy

konstruktoru

Page 18: Úvod do  objektov ě orientovaného programování

class bod{private: int x, y;

public: bod( int xx=0, int yy=0) { x=xx; y=yy; };

bod operator+( bod&); bod operator=( bod&);};

bod a(1,2), b, c;c = a + b;

Přetěžování operátorů - deklarace

implicitní parametry implicitní konstruktor

přetížení operátoru +

a + b a.operator+(b)

a = b a.operator=(b)

c.operator=(a.operator+(b));c.assign( a.add( b));

bod::bod(0,0);

Page 19: Úvod do  objektov ě orientovaného programování

bod bod::operator=( bod& b){ x = b.x; y = b.y; return *this;}

bod bod::operator+( bod& b){ return bod( x+b.x, y+b.y);}

Přetěžování operátorů – těla metod

co to je ??? vytvoření dočasného

objektu konstruktor bod::bod(int, int)

x this->x

kopie objektu(hodnotou přiřazení

je přiřazovaná hodnota)

aktualizace stavu

reference

Page 20: Úvod do  objektov ě orientovaného programování

bod bod::operator+=( bod& b){ x += b.x; y += b.y; return *this;}

Pozor!   Pro předefinované operátory nemusí platit identity definované pro základní typy:a=a+b a+=b a[b] *(a+b)

Přetěžování operátorů – ekvivalence

bod bod::operator+=( bod& b){ return *this = *this + b; }

this->operator=( this->operator+( b))

Page 21: Úvod do  objektov ě orientovaného programování

class bod{private: int x, y;

public: bod( bod& b) { x=b.x; y=b.y; };

bod operator=( bod& b) { x=b.x; y=b.y; return *this; };};

bod a(1,2);bod k, m(a), n = a;k = m;

copy konstruktor a operator=

copy konstruktordeklarace nového objektu

operator=přiřazení do existujícího

obj.

není-li copy konstruktor nebo operator= definován, automaticky se vygeneruje

copy konstruktor resp. operator= všech složek

Page 22: Úvod do  objektov ě orientovaného programování

bod a(1,2);

bod *pb = new bod;*pb = a + a;a = *pb;delete pb;

pb = new bod( a);bod *pc = new bod( 3, 5);a = *pb + *pc;delete pc;delete pb;

Operátory new a delete

dynamická alokace, implicitní

konstruktornáhrada za malloc()

uvolnění paměti

další alokace,explicitní

konstruktory

Page 23: Úvod do  objektov ě orientovaného programování

bod& rb = *new bod( 1,2);rb = rb + rb;delete &rb;

char* buf = new char[10];strcpy( buf, “ahoj”);...delete[] buf;

new a delete – pole a reference

alokace pole objektů

uvolnění paměti -

u alokovaných polí nutno []

dynamická inicializace reference

Page 24: Úvod do  objektov ě orientovaného programování

Chytré řetězce – nápad

str s1 = “ahoj”;str s2 = “babi”;str s3;

s3 = s1 + ‘ ‘ + s2;s3 += “.”;

‘obyčejné‘ zřetězení – nechci se starat o to, kde sebrat místo

Práce s řetězci v C+ efektivní – nepohodlá – chybyChtěl bych: přiřazování, spojování, alokace místa

s3 = malloc( strlen(s1) + strlen(s2) + 2);strcpy( s3, s1);s3[strlen(s1)] = ‘ ‘;strcpy( s3 + strlen(s1) + 1, s2);

Page 25: Úvod do  objektov ě orientovaného programování

Chytré řetězce - třídaclass str{private: char* buf;

public: str() { buf = 0; }; str( str& s); str( char* s); ~str() { delete[] buf; };

str& operator=( str& s); str operator+( str& s);

int len() { return buf ? strlen(buf) : 0; };};

ukazatel na alokovaná

dataimplicitní

konstruktor – prázdný řetězec

destruktor – objekt si musí po sobě

uklidit !(delete přežije i 0)

operace s řetězci

další metody (délka řetězce)

Page 26: Úvod do  objektov ě orientovaného programování

Destruktoryclass str{private: char* buf;

public: str() { buf = 0; }; str( char* s) { buf = new char[ strlen( s) + 1]; strcpy( buf, s); };

~str() { delete[] buf; };};

ukazatel na alokovaná

dataalokace

paměti pro řetězecdestruktor –

automaticky se volá při zrušení

objektu

nemá argumenty, nic

nevracíobjekt po sobě musí uklidit

Page 27: Úvod do  objektov ě orientovaného programování

Vyvolání destruktoru

fce(){ str s1 = “ahoj”; str* s2 = new str( “babi”); ..... delete s2; .....}

v kostruktoru s1 se alokuje paměť

dynamická alokace sp2

delete zavolá destruktor

(a potom uvolní paměť)

zde končí život s1, automaticky

se vyvolá destruktor

Page 28: Úvod do  objektov ě orientovaného programování

Řetězce – implementacestr& str::operator=( str& s){ delete[] buf; if( ! s.len()) { buf = 0; } else { buf = new char[ s.len()+1]; if( buf) strcpy( buf, s.buf); } return *this; }

str::str( str& s){ ....}

uklidit popředchozím

řetězciprázdný řetězec

copy konstruktor – totéž bez delete a return

alokace paměti

okopírování znaků

přiřazená hodnota – objekt sám

reference kvůli efektivitě

Page 29: Úvod do  objektov ě orientovaného programování

class str{private: char* buf; void copy( char* s);

public: str() { buf = 0; }; str( str& s) { copy( s.buf); }; str( char* s) { copy( s); }; ~str() { clear(); }; str& operator=( str& s) { clear(); copy( s.buf); return *this; }; str& operator=( char* s) { clear(); copy( s); return *this; }; void clear() { delete[] buf; };};

O něco lepší implementace

privátní metoda – provádí vlastní alokaci a kopírování

častopotřebujeme uklízet

později si ukážeme ještě lepší –

counted pointers

Page 30: Úvod do  objektov ě orientovaného programování

void str::copy( char* s){ if( !s || !*s) { buf = 0; } else { buf = new char[ strlen( s)+1]; if( buf) strcpy( buf, s); }}

Implementace kopírování

zkontrolovat prázdný řetězec

alokace a kopírování

předpokládámeprázdný buf

zařídí volající metoda – copy je private

Page 31: Úvod do  objektov ě orientovaného programování

str str::operator+( str& s){ str newstr; newstr.buf = new char[ len() + s.len() + 1]; strcpy( newstr.buf, buf); strcat( newstr.buf, s.buf); return newstr;}

str str::operator+( char* s){ ....}

Zřetězenínový prázdný řetězec

místo na znaky

první operand

druhý operand

návratová hodnota

Page 32: Úvod do  objektov ě orientovaného programování

class str{ ....public: .... str& operator=( str& s); str& operator=( char* s); str operator+( str& s); str operator+( char* s); str& operator+=( str& s) { *this = *this + s; return *this; }; str& operator+=( char* s) { *this = *this + s; return *this; };};

Připojení řetězce

když už umíme + a =proč si neudělat +=

operator+( str&) operator+( char*)

Page 33: Úvod do  objektov ě orientovaného programování

class str{ ...public: str(); str( str&); str( char*); str( int c) { buf = new char[ 2];

buf[0] = c; buf[1] = '\0'; };

str& operator=( str&); str& operator=( char*); str& operator=( int);

str operator+( int); str operator+=( int);};

Spolupráce str a int (jednotlivé znaky)

dodefinovat konstruktor,

přiřazení a operace pro další typ

dodefinovat konstruktor,

přiřazení a operace pro další typ

Page 34: Úvod do  objektov ě orientovaného programování

class str{ ...public: int print() { return buf ? printf( "%s", buf) : 0; };};

str s1 = "ahoj", s2("babi"), s3;s3 = s1 + ' ' + s2;s3.print();str("\n").print();(s3 += ".\n").print();

Výstup

neprázdný obsah na

stdout

později si ukážeme elegantnější řešení -

streams

‘normálně’ spojím řetězce s

mezerou ... a vytisknu

dočasný objekt

reference na s3

Page 35: Úvod do  objektov ě orientovaného programování

class str {private: char* buf; void copy( char* s);

public: str() { buf = 0; }; str( str& s); str( char* s); str( int c);

~str();

... and together

str& operator=( str& s); str& operator=( char* s); str& operator=( int c);

str operator+( str& s); str operator+( char* s); str operator+( int c);

str& operator+=( str& s); str& operator+=( char* s); str& operator+=( int c);

void clear(); int len(); int print();};

Page 36: Úvod do  objektov ě orientovaného programování

Vztah tříd předek-potomek – hierarchieVícenásobná dědičnost specializace (potomek má/umí něco navíc) reusabilita (jiné chování bez změny pův. třídy)

Dědičnost

protokoly - později

zvíře pes pitbul

člověk

jez, vyměšuj

sedni, lehni

trhej

uč_se

Page 37: Úvod do  objektov ě orientovaného programování

pes jako potomek zvířete - definice

class pes : public zvire{private: enum t_stav { Stoji, Sedi, Lezi }; t_stav stav;

public: pes() { stav = Stoji; };

int sedni() { stav = Sedi; }; t_stav codela() { return stav; }};

potomek

zvířeteclass zvire{private: int zaludek;

public: zvire(); zvire( int jidlo);

int zije(); int jez( int jidlo); int vymesuj( int objem);};

Page 38: Úvod do  objektov ě orientovaného programování

stav

pes jako potomek – obsah objektu

položkypotomk

a

jez, vyměšuj

žaludek sedni

položky předka

metody předka

metody potomk

a

zvire pytlik;pes azor;

pytlik.jez();azor.jez();azor.sedni();

potomek obsahuje

všechny položky a metody předka

Page 39: Úvod do  objektov ě orientovaného programování

Konstruktor předka

class pes : public zvire{ ...

public: pes() { stav = Stoji; }; pes( int jidlo) : zvire( jidlo) { stav = Stoji; };};

implicitní konstruktor předka

(automaticky)

explicitní konstruktor předka

konstruktory předků a

vložených třídse volají před

konstruktorem potomka

Page 40: Úvod do  objektov ě orientovaného programování

Destruktor předkaclass zvire{ ...

~zvire() { printf( "zabijim zvire "); };};

class pes : public zvire{ ...

~pes() { printf( "zabijim psa "); };};

{ pes azor; ...}

destruktor předkase vyvolá

automaticky po ukončení

destruktoru potomka

zabijim psazabijim zvire

Page 41: Úvod do  objektov ě orientovaného programování

Potomka lze přiřadit do předka (platí i pro ukazatele)Předka NELZE přiřadit do potomka (platí i pro uk.)

Kompatibilita předka a potomka

pes umí jíst, brouk neumí štěkat azor

zvire pytlik, *pz;pes azor, *pp;

pytlik = azor;*pz = &azor;

azor = pytlik;*pp = &pytlik;

stavžalude

k

pytlikžalude

k

stavžalude

kžalude

k

pytlik

azor

???nelze

Page 42: Úvod do  objektov ě orientovaného programování

odlišné chování potomků – pozdní vazba (late binding)

Polymorfismus

najde něco v přírodě

zvíře pes pitbul

člověk

jez jez jez

jez

sní maso sní hodně masa

jde do restaurac

e

Page 43: Úvod do  objektov ě orientovaného programování

Polymorfismus - motivace

class zvire{ jez() { priroda(); };};

class pes : public zvire{ jez() { maso(1); };};

class pitbul : public pes{ jez() { maso(10); };};

class clovek : public zvire{ jez() { hospoda(); };};

zvire pytlik;pes punta;pitbul zorro;clovek pepa;

pytlik.jez(); // priroda();punta.jez(); // maso(1);zorro.jez(); // maso(10);pepa.jez(); // hospoda();

Tohle není polymorfismus !

'normální' vlastnost třídzakrývání metod

Při překladu je známoze které třídy se volá

metoda

Page 44: Úvod do  objektov ě orientovaného programování

Polymorfismus – takto nelze

zvire* z;

z = new pes;z->jez(); // priroda();

z = new clovek;z->jez(); // priroda();

z je ukazatel na zvíře

volá se zvire::jez()

nelze (syntaktická chyba, pes není

předkem zvířete)

zvire* z;

z = new pes;z->pes::jez(); // priroda();

z = new clovek;z->clovek::jez(); // priroda();

Page 45: Úvod do  objektov ě orientovaného programování

Polymorfismus – takto bych to chtěl

zvire* z;

z = new pes;z->jez(); // maso(1);

z = new clovek;z->jez(); // hospoda();

zvire* nase_rodina[3];

nase_rodina[0] = new clovek;nase_rodina[1] = new pes;nase_rodina[2] = new pitbul;

for( int i = 0; i < 3; i++) z->jez();

Pokaždé se zavolá jiná metoda

Rozlišení metody se děje za běhu

Pokaždé se zavolá jiná metoda

Rozlišení metody se děje za běhu

Page 46: Úvod do  objektov ě orientovaného programování

Virtuální funkce - deklarace

class zvire{ virtual jez() { priroda(); };};

class pes : public zvire{ virtual jez() { maso(1); };};

class pitbul : public pes{ virtual jez() { maso(10); };};

class clovek : public zvire{ virtual jez() { hospoda(); };};

magické klíčové

slovo virtual

každý objekt si s sebounese informaci

kterou virtuální funkci používá

Page 47: Úvod do  objektov ě orientovaného programování

Virtuální funkce - implementace

pes

stav

žaludek

zvirežalude

k

z = new zvire;

jez

zvire::jez() { priroda(); };

jez

pes::jez() { maso(1); };

z = new pes;

zvire * z;

z->jez();

tabulka virtuálních funkcí

tabulka virtuálních funkcí

zavolá se správná metoda

Page 48: Úvod do  objektov ě orientovaného programování

Virtuální funkce a konstruktory

class A{ public: virtual f(); A() { f(); }; // A::f~A() { f(); }; // A::f g() { f(); }; // A/B::f};

class B : public A{ public: virtual f(); B() { f(); }; // A::A B::f~B() { f(); }; // B::f A::~A g() { f(); }; // B::f};

Page 49: Úvod do  objektov ě orientovaného programování

Volání virtuálních funkcíA a; // A::AB b; // B::BA * paa = &a;A * pab = &b;B * pbb = &b;

a.f(); // A::fb.f(); // B::f

paa->f(); // A::f pab->f(); // B::fpbb->f(); // B::f

b.A::f(); // A::fb.B::f(); // B::fa.B::f(); // NE!paa->A::f(); // A::fpab->A::f(); // A::fpab->B::f(); // NE!pbb->A::f(); // A::fpbb->B::f(); // B::f

pozdní vazba

b B::f

paaA::fa

pab

pbb

kvalifikované volání

Page 50: Úvod do  objektov ě orientovaného programování

Abstraktní třída, čistě virtuální funkce

int armada;

class vojak{ public: enum THod { vojin, desatnik, porucik, general };private: THod hodnost;public: vojak( THod hod = vojin) { hodnost=hod; armada++; }; virtual void pal() = 0; ~vojak() { armada--; };};

class samopal {};class kalasnikov : public samopal {};

class pesak : public vojak{private: samopal* sam;public: pesak( THod hod=vojin) : vojak( hod) { sam = new kalasnikov; }; virtual void pal() { sam->pal(); }; ~pesak() { delete sam; };};

pure virtual functionabstraktní třída

POZOR!!!Nutný virtuální

destruktor

Page 51: Úvod do  objektov ě orientovaného programování

Abstraktní třídy, virtuální destruktory

vojak v; // NELZE – abstraktní třídapesak p; // OK – pesak vojinpesak* pp = new pesak; // OKpp->pal(); // pesak::palvojak* v = new pesak; // OKv->pal(); // pesak::paldelete pp; // OK, pesak::~pesakdelete v; // !!! vojak::~vojak

class vojak{ virtual ~vojak() { armada--; };};

class pesak : public vojak{ virtual ~pesak() { delete sam; };};

POZOR!!! nejsou-li destruktory

virtuální,nezruší se samopal

Řešení:virtuální

destruktor

Page 52: Úvod do  objektov ě orientovaného programování

Prostory jmen (namespaces)

namespace aa { int p; int f1( int x) { return x + p; } int f2( int x, int y);}

int aa::f2( int x, int y){ return p * (x + y);}

aa::f1( aa::f2( 5, 6));

zapouzdření identifikátorůprevence kolizí (velké projekty, knihovny)stejné identifikátory v různých prostorech jmen

definice prostoru jmen

přístup k identifikátoru ze

stejného prostorudefinice funkce

mimo prostor jmen

přístup k identifikátorům přes

::

Page 53: Úvod do  objektov ě orientovaného programování

using namespace std;

namespace aa { int p; int q;}

int g( int n) { cout << (n + aa::p);}

namespace aa { int f3( int x) { return 1 + ::g( x);}

Prostory jmenprostor jmen se může opakovaně otevírat a zavíratexplicitní přístup ke globálnímu identifikátoru ::idstandardní knihovny – namespace std

rozbalení std

znovuotevřeníprostoru aa

přístup do aa

přístup ke globálnímu

identifikátoru

přístup k identifikátorům std

Page 54: Úvod do  objektov ě orientovaného programování

Prostory jmen a standardní knihovny

stará konvence: stdio.h, ctype.h, iostream.h identifikátory v globálním prostoru jmen

nová konvence: cstdio, cctype, iostream identifikátory uzavřené do namespace std

standardní knihovny C++ Základní knihovny z C přejmenované podle nové konvence Rozšířené C++ knihovny iostream: znakový formátovaný vstup a výstup STL: Standard Template Library

Page 55: Úvod do  objektov ě orientovaného programování

#include <iostream>using namespace std;

int main(){ int n; cout << "Rekni cislo: "; cin >> n; cout << "Mam vic: " << (n+1) << ", hec!" << endl;}

Vstup a výstup - proudy (streams)

hierarchie tříd pro (formátovaný znakový) vstup a výstupjednotné rozhraní pro v/v do souborů a paměti, ...operátory << a >>, manipulátory, snadné rozšiřování definice základních

tříd a manipulátorů

ostream cout FILE* stdout istream cin FILE* stdin

ostream& ostream::operator<< ( )

Page 56: Úvod do  objektov ě orientovaného programování

Streams – hierarchie tříd

Page 57: Úvod do  objektov ě orientovaného programování

<iostream> – základní operace, standardní v/v, manip. bez parametrů

cin, cout, <<, >>, endl, ws, ...<iomanip> – manipulátory s parametry

setw, setfill, ...<fstream> – vstup a výstup do souborů

fstream, ifstream, ofstream, ...<strstream> - vstup a výstup do paměti (chytré řetězce)

strstream, istrstream, ostrstream, ...

Hlavičkové soubory

Page 58: Úvod do  objektov ě orientovaného programování

do proudu lze vkládat manipulátory – změní stav proudu

endl pošle buffer na výstup a odřádkujeleft, right zarovnávej doleva / dopravadec, hex v desítkové / šestnáctkové soustavěws přeskoč bílé znaky (na vstupu)setw(int) šířka výstupního pole (jen pro násl. číselnou položku)setfill(int) výplňkový znak... a spousty dalších

[...17]cout << "[" << setfill('.') << setw(5) << 17 << "]" << endl;

Manipulátory

Page 59: Úvod do  objektov ě orientovaného programování

#include <fstream>using namespace std;

int main(){ fstream f( "C:\\src\\pokus.txt", ios::out); if( ! f) error(); f << "bubu" << endl;}

Výstup do souboruspojení proudu se

souborem v konstruktoru

způsob otevřeníios::in, out, app, trunc,

binary, ...

operator ! (ostream&)vrátí true když se

operace nepodařila

soubory není třeba zavírat, zavře je automaticky

destruktor

Page 60: Úvod do  objektov ě orientovaného programování

Další metody vstupních proudůpro binární vstup a výstup nelze použít operátory << a >>

Vstup get( kam, délka, koncový_znak) getline( kam, délka, koncový_znak) ignore( délka, koncový_znak) read( pole_znaků, délka) tellg() seekg( posun, odkud) unget() peek()

Page 61: Úvod do  objektov ě orientovaného programování

Další metody výstupních proudů

Výstup get( kam, délka, koncový_znak) put( znak) write( pole_znaků, délka) tellp() seekp(posun, odkud) flush()

... a další

int i = 17;ofstream f( "pokus.txt", ios::binary);if( ! f) error();f.write( (char*)&i, sizeof( i));

pole bajtů a jejich počet

Page 62: Úvod do  objektov ě orientovaného programování

Spřátelené funkce – vlastní výstup

class complx {private: int re, im;public: complx( int _re = 0, int _im = 0) { re = _re; im = _im; };

friend ostream& operator<<( ostream& s, complx& c){ return s << c.re << "+" << c.im << "i"; };

};

complx x(1,2);cout << x << endl;

spřátelená (friend) funkce může přistupovat k privátním

položkám

POZOR!

Toto není

metoda třídy!

Page 63: Úvod do  objektov ě orientovaného programování

množina funkcí/objektů lišících se pouze typem parametrů/položekvzor, podle kterého překladač vytvoří funkci nebo třídu - instanci

template <class T> T max( T a, T b){ return a > b ? a : b;};

int x = 10, y = 20;double m = 1.1, n = 2.2;cout << max(x,y) << max(m,n) << endl;

Šablony

Definice šablony funkce

Typový parametr T nahrazuje skutečný

typ

int max( int a, int b)

double max( double a, double b)

Page 64: Úvod do  objektov ě orientovaného programování

template<class T> class guma{private: int size; T* array;public: enum { default_size = 10 }; guma( int _size = default_size) { size = _size; array = new T[size]; }; ~guma() { delete array; } T& operator[] (int n);};

int main(int argc, char* argv[]){ guma<int> ip(5); ip[3] = 999;

Šablony tříd - definice

přetížený operator[]

size: 5array:

0 1 2 3 4

? ? ? ? ?

instance šablony třídy

definice proměnné

pole neznáméh

o typu

Page 65: Úvod do  objektov ě orientovaného programování

template<class T> class guma{ private: int size; T* array;public: T& operator[] (int n);};

template<class T> T& guma<T>::operator[] (int n){ if( n >= size) { T* na = new T[ n + 1]; for( int i = 0; i < size; i++) na[i] = array[i]; delete array; array = na; size = n + 1; } return array[n];}

Šablony metod, instance šablonstruct krabice{ int a, b; char jm[10];};

typedef guma<krabice> polekrab;

int main(int argc, char* argv[]){ guma<int> ip(5); polekrab pk; ip[3] = 999; pk[12].a = ip[3];

instancešablony třídy

definice typu

pk[i] je typu

krabice&

definice šablony metody

Page 66: Úvod do  objektov ě orientovaného programování

list<int> sez;sez.push_front( 1);sez.push_back( 2);sez.push_front( 3);list<int>::iterator i;for( i = sez.begin(); i != sez.end(); i++)

cout << "[" << *i << "]";

STL – Standard Template Library

obousměrný seznam

kontejnery – datové struktury pro ukládání dat a manipulaci s nimiiterátory – třídy pro přístup k datům kontejnerůalgoritmy – základní algoritmy nad kontejnery (třídění, procházení, hledání)další pomocné třídy – alokátory, komparátory, funktory ...

přidání prvku zepředu ...

zezadu ... zepředuiterátor seznamu

průchod seznamem

přístup k datům přes iterátor – operator*

Page 67: Úvod do  objektov ě orientovaného programování

STL – kontejnery

deque – dvoustranná fronta (implementace: pomocí polí)stack, queue, priority_queue – fronta, zásobníkvector – polelist – dvousměrný seznam (implementace: spojový seznam)map, multimap – zobrazení, asociativní pole, slovník, mapa

(uspořádaná struktura indexovaná libovolným typem, pair: klíč, hodnota)set – množina (každý prvek nejvýše jednou)string – chytré řetězce (+, +=, mnoho dalších operací a metod)

Page 68: Úvod do  objektov ě orientovaného programování

STL – iterátory a metody kontejnerů

kontejner<T>::iterator iterátor příslušného kontejneruT& iterator::operator*přístup k prvku přes iterátor

begin(), end() iterátor na začátek / za(!) konec kontejnerupush_front(T), push_back(T) přidání prvku na začátek / konecpop_front(), pop_back() odebrání prvku ze začátku / konce – nevrací!push(T), pop() přidání a odebrání z fronty / zásobníkufront(), back(), top() prvek na začátku fr. / konci fr. / vrcholu zás.operator[], at() přímý přístup k prvkuinsert(iterator,T) vložení prvku na místo určené iterátoremsize(), empty(), clear() velikost / neprázdost / smazání kontejneru

Page 69: Úvod do  objektov ě orientovaného programování

map<string,string> ts;

ts["Filip"] = "605123456";ts["Petra"] = "721334455";ts["David"] = "723654321";ts["Kuba"] = "222333444";

cout << "Telefon Petry: " << ts["Petra"] << endl;

map<string,string>::iterator ti;

for( ti = ts.begin(); ti != ts.end(); ti++) cout << ti->first << ": " << ti->second << endl;

STL – použití asociativního pole

pair<string,string> iterator::operator*

ts: pair:

string second

string first

Page 70: Úvod do  objektov ě orientovaného programování

STL – generické algoritmyAlgorithms initializing a sequencefill Fills a sequence with an initial valuefill_n Fills n positions with an initial valuecopy Copies a sequence into another sequencecopy_backward Copies a sequence into another sequencegenerate Initializes a sequence using a generatorgenerate_n Initializes n positions using a generator swap_ranges Swaps values from two parallel sequences

Searching algorithmsfind Finds an element matching the argument find_if Finds an element satisfying a condition adjacent_find Finds consecutive duplicate elements find_first_of Finds one member of a sequence in another seq.find_end Finds the last occurrence of a sub-seq. in a seq.search Matches a sub-sequence within a sequence max_element Finds the maximum value in a sequence min_element Finds the minimum value in a sequence mismatch Finds first mismatch in parallel sequences

Removal algorithms remove Removes elements that match conditionunique Removes all but first of duplicate values

Algorithms for in-place transformationsreverse Reverses the elements in a sequence replace Replaces specific values with new value replace_if Replaces elements matching predicaterotate Rotates elements in a sequence around a point partition Partitions elements into two groups stable_partition Partitions preserving original ordering next_permutation Generates permutations in sequence prev_permutation Generates permutations in reverse sequence

inplace_merge Merges two adjacent sequences into one random_shuffle Randomly rearranges elements in a sequence

Scalar generating algorithmscount Counts number of elements matching value count_if Counts elements matching predicateaccumulate Reduces sequence to a scalar value inner_product Gives inner product of two parallel sequencesequal Checks two sequences for equality lexicographical_compare Compares two sequences

Sequence generating algorithms transform Transforms each elementpartial_sum Generates sequence of partial sums adjacent_difference Generates sequence of adjacent differences

Miscellaneous operations for_each Applies a function to each element of a collection

Page 71: Úvod do  objektov ě orientovaného programování

STL – chybová hlášení\SRC\templ\templ.cpp(101) : error C2664: 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::iterator __thiscall std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::insert(class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::iterator,const struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > &)' : cannot convert parameter 1 from 'char [6]' to 'class std::_Tree<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,struct std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::_Kfn,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >::iterator'

Page 72: Úvod do  objektov ě orientovaného programování

VýjimkyMotivace: co dělat, když (knihovní) funkce zjistí chybu?nedostatek paměti, nelze otevřít soubor, nulový ukazatel, ...Vypsat zprávu na 'obrazovku' a skončit FUJ! Nikdy!Nastavit do globální funkce příznak chybyVrátit 'divnou' hodnotu – takhle funguje většina knihovních funkcí Cnepříliš praktické, testování každé funkce, vnořené testy,divná hodnota nemusí existovat, ...Co chceme:- oddělit detekci výjimečné situace od jejího zpracování- po výskytu 'chyby' (výjimečné situace) automaticky skočit na zpracování- kulturně po sobě uklidit (volání destruktorů)Řešení v C++: mechanismus výjimek

Page 73: Úvod do  objektov ě orientovaného programování

void mojefce( char* str){ if( ! str) throw runtime_error( "Nic!"); cout << str;}

int main(int argc, char* argv[]){ char* p = 0;

try { mojefce( p); } catch( runtime_error& e) { cout << "Chyba: " << e.what() << endl; }

return 0;}

Výjimky - jednoduchý příkladvyvolání výjimkytyp výjimky

standardní třídapotomek exception

pokusný blok

try blocktry blockhandler(y)typ výjimky

standardní metoda třídy runtime_error

řetězec z konstruktoru

Page 74: Úvod do  objektov ě orientovaného programování

Výjimky - pravidla k try bloku může být několik handlerů s různými typy try bloky mohou být vnořené výjimka může být vyvolána v libovolně zanořené funkci po vyvolání výjimky se řízení předá handleru s odpovídajícím typem před odchodem ze všech bloků se zavolají destruktory lokálních objektů

předávaná hodnota nese informaci o výjimce typické použití: potomek standardní třídy exception i pro výjimky platí, že potomek může nahradit předka konstruktor runtime_error(string&), metoda string what() po ošetření výjimky pokračuje program za handlery try bloku při běhu bez výjimky se handlery ignorují (přeskočí) neošetřená výjimka – unhandled exception, konec programu

Page 75: Úvod do  objektov ě orientovaného programování

Specifikace výjimek funkcí

Problém: jak programátor pozná které výjimky má ošetřovat?Řešení: funkce může specifikovat výjimky, které může vyvolat

void mojefce( char* s) throw (runtime_error, mojechyba);

int jinafce( void) throw();

char* tretifce( char* s);

funkce může vyvolat výjimky těchto typů

funkce nevyvolává žádnou výjimku

funkce může vyvolat libovolnou výjimku

Page 76: Úvod do  objektov ě orientovaného programování

... co jsme neprobrali spoustu věcí Jazyk

const, protected, volatile, static, operátory .* a ->*, ukazatele na funkce, ...

vícenásobná dědičnost, protokoly RTTI, typeid, type_info static_cast, dynamic_cast, reinterpret_cast podrobněji knihovny

OOP counted pointers, mělké vs. hluboké kopie objektová paradigmata – zprávy, obálkové třídy, subtyping, forwarding hlouběji o objektovém návrhu, reusabilitě, efektivitě implementace funktory a jiné specialitky

spoustu věcí


Recommended