You are on page 1of 58

PB161

PB161 Programovn v jazyce C++


Objektov Orientovan Programovn
STL algoritmy, Funktory, Vjimky
STL algs, Vjimky, Functor 3.11.2014
1
PB161
Organizan - zvan pednky
24.11. Juraj Michlek (YSoft)
1.12. Ji Weiser (Laborato Paradise) - C++11

STL algs, Vjimky, Functor 3.11.2014
2
PB161
STL Algoritmy
STL algs, Vjimky, Functor 3.11.2014
3
PB161
STL zavd nov koncepty
1. Kontejnery
objekty, kter uchovvaj jin objekty bez ohledu na typ
kontejnery rzn optimalizovny pro rzn typy loh
nap. std::string (uchovv pole znak)
nap. std::list (zetzen seznam)
2. Itertory
zpsob (omezenho) pstupu k prvkm kontejneru
nap. std::string.begin()
peten opertory ++ pro pesun na dal prvek atd.
3. Algoritmy
bn operace vykonan nad celmi kontejnery
nap. sort(str.begin(), str.end())
STL algs, Vjimky, Functor 3.11.2014
4
6
.

P

e
d
n

k
a


PB161
STL Algoritmy
Standardn metody pracujc nad kontejnery
Obsahuje asto pouvan operace (hledn,
azen)
Mohou kontejner st nebo i mnit
asto vyuvaj (jako argument) itertory

STL algs, Vjimky, Functor 3.11.2014
5
// sort algorithm example from http://www.cplusplus.com/reference/algorithm/sort/
#include <algorithm>
#include <vector>
using namespace std;

int main () {
vector<int> myvector;
// fill vector by values
sort (myvector.begin(), myvector.end());
return 0;
}
PB161
Algoritmy - dokumentace
STL algs, Vjimky, Functor 3.11.2014
Funkce dostupn v <algorithm>
http://www.cplusplus.com/reference/algorithm/
Ukzka syntaxe na for_each



6
PB161
Zkladn dostupn STL algoritmy
Vyhledvn, statistika (nemodifikuj clov kontejner)
find(), search(), count()
Modifikuj clov kontejner
copy(), remove(), replace(), transform()
Aplikace uivatelsk funkce
for_each() (typicky) nemodifikuje pvodn kontejner
transform() (typicky) modifikuje obsah kontejneru
adc
sort()
vhodn adc algoritmus automaticky vybrn dle typu kontejneru
Spojovn rozsah, Minimum, maximum
A spousta dalch
http://www.cplusplus.com/reference/algorithm/
STL algs, Vjimky, Functor 3.11.2014
7
PB161
STL algs, Vjimky, Functor 3.11.2014
8
P

e
v
z
a
t
o

z


h
t
t
p
:
/
/
w
w
w
.
c
p
l
u
s
p
l
u
s
.
c
o
m
/
r
e
f
e
r
e
n
c
e
/
a
l
g
o
r
i
t
h
m

PB161

STL algs, Vjimky, Functor 3.11.2014
9
P

e
v
z
a
t
o

z


h
t
t
p
:
/
/
w
w
w
.
c
p
l
u
s
p
l
u
s
.
c
o
m
/
r
e
f
e
r
e
n
c
e
/
a
l
g
o
r
i
t
h
m

PB161
STL algoritmy find


STL algs, Vjimky, Functor 3.11.2014
10
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
using std::cout;
using std::endl;
int main() {
std::list<int> myList;
myList.push_back(1);myList.push_back(2);myList.push_back(3);
myList.push_back(4);myList.push_back(5);
// 1, 2, 3, 4, 5

std::list<int>::iterator iter;
// Find item with value 4
if ((iter = std::find(myList.begin(), myList.end(), 4)) != myList.end()) {
cout << *iter << endl;
}
// Try to find item with value 10
if ((iter = std::find(myList.begin(), myList.end(), 10)) != myList.end()) {
cout << *iter << endl;
}
else cout << "10 not found" << endl;
return 0;
}
PB161
STL algoritmy for_each a transform


STL algs, Vjimky, Functor 3.11.2014
11
#include <iostream>
#include <list>
#include <algorithm>
using std::cout;
using std::endl;
int increase10(int value) {
return value + 10;
}
void print(int value) {
cout << value << endl;
}
int main() {
std::list<int> myList;
// fill something into myList
// Apply function to range (typically non-modifying)
std::for_each(myList.begin(), myList.end(), print);
// Apply function to range (will work only for integers) (modifying)
std::transform(myList.begin(),myList.end(),myList.begin(),increase10);
return 0;
}
for_each me tak modifikovat kontejner
Pokud je hodnota pedvna referenc
print(int& value)
Pro modifikaci pouvejte ale radji transform
PB161
STL algoritmy callback funkce
Nkter algoritmy berou jako parametr funkci
aplikuj ji na prvky kontejneru





Me bt klasick C funkce (nap. print())
Me bt static metoda objektu (viz. dle)
Me bt objekt s petenm opertorem()
tzv. functor, viz dnes pozdji
Me bt lambda (C++11, pozdj pednka)


STL algs, Vjimky, Functor 3.11.2014
12
std::for_each(myList.begin(), myList.end(), print);
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f)
{
for ( ; first!=last; ++first ) f(*first);
return f;
}
PB161
STL algoritmy sort


STL algs, Vjimky, Functor 3.11.2014
13
// sort algorithm example from http://www.cplusplus.com/reference/algorithm/sort/
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

bool myfunction (int i,int j) { return (i<j); }

int main () {
int myints[] = {32,71,12,45,26,80,53,33};
vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33
vector<int>::iterator it;

// using default comparison (operator <):
sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33

// using function as comp
sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

cout << endl;

return 0;
}
PB161
Funkn objekty
STL algs, Vjimky, Functor 3.11.2014
14
PB161
Funkn objekt - motivace
Z C/C++ jsou znm tzv. callback funkce
pomoc funknho ukazatele je mon pedat jako parametr ukazatel na
funkci, kter je pozdji zavolna
pouv se napklad u STL algoritm
std::for_each(l.begin(),l.end(), print);




Co kdy chceme pitat pomoc std::transform slo 10?
vytvome funkci int add10(int value){return value+10;}
std::transform(l.begin(),l.end(),l.begin(),add10);
Co kdy chceme pitat libovoln slo?
STL algs, Vjimky, Functor 3.11.2014
15
PB161
Funkn objekt Functor
Objekt, kter me zavoln, jako by to byla bn
funkce
doshneme pomoc petenho opertoru()
A prom; prom(5);
Opertor () musme petit pro vechny potebn
typy a poty argument
tj. pro kadou funkci, kterou chceme functorem nahradit
jeden functor me nahrazovat nkolik funkc (jak?)
Pokud se pokusme pout objekt jako functor a
neexistuje odpovdajc peten opertor ()
error: no match for call to '(typ_objektu) (typ_argument)'
stl_algo.h:4688:2: error: no match for call to '(A) (int&)'
STL algs, Vjimky, Functor 3.11.2014
16
PB161
Functor - ukzka

STL algs, Vjimky, Functor 3.11.2014
17
#include <iostream>
#include <list>
#include <algorithm>

class CAddX {
int m_whatAdd;
public:
CAddX(int whatAdd) : m_whatAdd(whatAdd) {}
void set(int whatAdd) { m_whatAdd = whatAdd; }
int operator () (int value) {
return value + m_whatAdd;
}
};
int main() {
std::list<int> myList;

myList.push_back(1); myList.push_back(2);
myList.push_back(3); myList.push_back(4);

CAddX variableAdder(3);
// variableAdder is functor object, now adding number 3
transform(myList.begin(), myList.end(), myList.begin(), variableAdder);
// change added value
variableAdder.set(101);
transform(myList.begin(), myList.end(), myList.begin(), variableAdder);

return 0;
}
Nyn pita trojky
Nyn pita stojedniky
PB161
Functory vhodnost pouit
Vhodou je monost uchovvat (a mnit) stav
functoru
u funkc bychom museli pout globln promnn
Functor me bt vrazn rychlej ne funkce
peklada me vloit kd functoru namsto voln
u funknch ukazatel (callback) nen mon
Vyuv mylenek z funkcionlnm programovn
souasn imperativn jazyky maj podporu pro nkter
funkn prvky
Functor, delegates a lambda vrazy... (C++11, C#...)
STL algs, Vjimky, Functor 3.11.2014
18
PB161
Pklad - kompozice funktor
Aplikace srie funkc na zadan argument
Nap. pseudozpis 'a(b(c(d(5))))' znamen, e
funkce a, b, c a d jsou aplikovny na argument 5.
kolem je vytvoit program umoujc vytvet
(aritmetick) funkce sloen z jednoduch
funktor
Definice vhodnho rozhran a vyuit ddinosti


STL algs, Vjimky, Functor 3.11.2014
19
PB161
Hierarchie
STL algs, Vjimky, Functor 3.11.2014
20
UnaryFunction i FunctionCompositor
maj peten opertor () a budou
pouity jako functory
PB161

STL algs, Vjimky, Functor 3.11.2014
21
class UnaryFunction {
public:
virtual ~UnaryFunction() {}
virtual int operator() (int arg) const = 0;
};

class UnaryNumericFunction : public UnaryFunction {
public:
UnaryNumericFunction(int rightOperand) : rightOperand_m(rightOperand) {}

virtual int rightOperand() const { return rightOperand_m; }
virtual void setRightOperand(int r) { rightOperand_m = r; }

private:
int rightOperand_m;
};


class Adder : public UnaryNumericFunction {
public:
Adder(int r) : UnaryNumericFunction(r) {}
int operator() (int arg) const { return arg + rightOperand(); }
};

class Multiplier : public UnaryNumericFunction {
public:
Multiplier(int r) : UnaryNumericFunction(r) {}
int operator() (int arg) const { return arg * rightOperand(); }
};

Petme opertor () pro
aplikaci unrn funkce
Numerick unrn funkce je
functor s parametrizac v
rightOperand_m
V petienm opertoru ()
pitme
Parametrizace functoru
PB161

STL algs, Vjimky, Functor 3.11.2014
22
// Function for deallocation
void delete_ptr(UnaryFunction* ptr) { delete ptr; }

class FunctionCompositor {
public:
FunctionCompositor() {}
~FunctionCompositor() {
// Use for_each algorithm to deallocate separate functions
std::for_each(functions_m.begin(), functions_m.end(), delete_ptr);
}

void appendFunction(UnaryFunction* fn) { functions_m.push_back(fn); }
void prependFunction(UnaryFunction* fn) { functions_m.push_front(fn); }

int operator() (int arg) {
typedef std::list<UnaryFunction*>::iterator iterator;
for (iterator it = functions_m.begin(); it != functions_m.end(); ++it) {
UnaryFunction* fnc = *it; // Get particular function
arg = (*fnc)(arg); // Apply it on argument
}

return arg;
}

private:
std::list<UnaryFunction*> functions_m;
};
Parametrizace functoru
probh pidvnm
unrnch funkc
Aplikac functoru pomoc
opertoru () postupn
zavolme vechny
obsaen funkce
PB161
Pouit functor

STL algs, Vjimky, Functor 3.11.2014
23
#include <iostream>
#include <algorithm>
#include <list>

int main() {
FunctionCompositor comp;
comp.prependFunction(new Adder(10));
comp.prependFunction(new Multiplier(2));
comp.prependFunction(new Adder(-5));
comp.prependFunction(new Adder(2));

int number = 0;
std::cin >> number;
std::cout << comp(number) << std::endl;
}
Vytvme functor comp
Vytvme functor typu
Adder (a dal) a
vkldme do comp
Aplikujeme functor comp
PB161
Vjimky (Exceptions)
STL algs, Vjimky, Functor 3.11.2014
24
PB161
Obsluha chyby bez vjimek

STL algs, Vjimky, Functor 3.11.2014
25
int foo(std::string name) {
int status = 0;
Person person(name);
if (status == 0) {
if (person.isValidName()) {
cout << "Valid person " << person.getName() << endl;
}
else status = -1; // signalize problem with name
}
if (status == 0) { // Still no problem?
std::string message;
message = "My favourite person is ";
message += person.getName();
cout << message << endl;
}
if (status == 0) { // Still no problem?
// ... do something else
}
if (status != 0) { // Some problem?
// ... report problem, roll back info....
}
return status;
}
Promnn s
hodnotou chyby
(0 == OK)
Test, zda se
nevyskytla chyba
V ppad chyby
nastav status
Kad dal logick
blok kdu obalen
testem na OK
Vra informaci o
prbhu
Udlej nco v reakci
na problm
PB161
Vjimky motivace
Vskyt situace, kterou je poteba okamit eit
nedostatek pamti
nepovolen pstup do pamti
dlen nulou
Me nastat kdekoli v kdu a me bt eiteln
uvolnme nepotebnou pam a zkusme znovu
vypeme varovn uivateli a nulou dl nedlme
Zrove ale nen praktick mt reagujc kd na v
kad metod
nedostaten pam me nastat kdekoli
STL algs, Vjimky, Functor 3.11.2014
26
PB161
Vjimky - syntaxe
Oznaen oblasti kde zachytvat vjimku
klov slovo try


Zachycen vjimky
klov slovo catch
jeden nebo vce blok
specifikace objektu vjimky typicky jako reference
(Vyvoln vjimky)
klov slovo throw

STL algs, Vjimky, Functor 3.11.2014
27
try {
// some code

throw std::logic_error("Problem");

// some code (not executed)
}
catch (std::logic_error& ex) {
// handle somehow exception
cout << ex.what() << endl;
}
PB161
Vjimky (Exception) - princip
1. V ppad vskytu problmu se vyvol vjimka
objekt obsahujc informaci o problmu
meme vyvolat i vvoj programov (throw)
2. Vjimka postupn stoup volajcmi funkcemi
(callstack), dokud ji nkdo nezachyt
3. Vjimka je zachycena obslunm blokem
specifikuje, v jak sti kdu a jak vjimky zachytvat
try/catch blok
4. Na zklad vjimky probhne programov reakce
ukonen programu
vpis varovn uivateli
exception handling
STL algs, Vjimky, Functor 3.11.2014
28
PB161
Ukzka

STL algs, Vjimky, Functor 3.11.2014
29
int main() {
cout << "Code before exception handling" << endl;
try {
Person p1("Pepa Novak"); // No problem
Person p2("");

p1.print();
p2.print();
}

catch (WrongNameExceptionExt& ex) {
cout << "WrongNameExceptionEx: " << ex.what();
}

cout << "Continuing after block with exception handling";

return 0;
}
class Person {
std::string m_name;
public:
Person(const std::string name) : m_name(name) {
if (m_name.size() == 0)
throw WrongNameExceptionExt("Invalid empty name");
}
void print() const { cout << m_name << endl; }
};
Vjimka vyvolna
Vjimka zachycena,
obslouena a zanik
Kd nebude vykonn
Program pokrauje
1.
2.
3.
PB161
Datov typ vjimky
Primitivn datov typy
nap. int, char
throw 1; catch (int ex) { }
throw 'e'; catch (char ex) { }
Struktury, tdy
struktury nebo tdy definovan programtorem
MyStructException ex; throw ex;
catch (MyStructException& ex) { }
Potomci std::exception
nejastji potomci std::logic_error nebo std::runtime_error
class MyException : public std::logic_error {
catch (std::logic_error& ex) {}
STL algs, Vjimky, Functor 3.11.2014
30
PB161

STL algs, Vjimky, Functor 3.11.2014
31

int main() {
cout << "Code before exception handling;

try {
foo(4); // throw exception

cout << "Will not be printed";
}
catch (int ex) {
cout << "Integer exception: " << ex;
}
catch (char ex) {
cout << "Char exception: " << ex;
}
catch (MyStructException& ex) {
cout << "Struct exception : " << ex.reason;
}
catch (MyException& ex) {
cout << "class MyException : " << ex.what();
}

cout << "Continuing after block with EH;

return 0;
}

#include <iostream>
#include <stdexcept>
#include <string>
using std::cout;
using std::endl;

struct MyStructException {
std::string reason;
int someValue;
};

class MyException : public std::invalid_argument {
public:
MyException(const std::string& reason = "") :
std::invalid_argument(reason) {}
};

void foo(int what) {
if (what == 1) throw 1;
if (what == 2) throw 'e';
if (what == 3) {
MyStructException ex;
ex.reason = "Just testing";
ex.someValue = -1;
throw ex;
}
if (what == 4) throw MyException("Just testing");
}
Vyhazuje
rzn typy
vjimek podle
what
foo(1)
foo(2)
foo(3)
foo(4)
PB161
Standardn vjimky
Vjimky jsou vyvolvan
jazykovmi konstrukcemi (nap. new)
funkcemi ze standardn knihovny (nap. STL algoritmy)
uivatelskm kdem (vraz throw)
Zkladn tda std::exception
#include <stdexcept>
metoda exception::what() pro zskn specifikace dvodu
Dv zkladn skupiny standardnch vjimek
std::logic_error chyby v logice programu
nap. chybn argument, ten za koncem pole
std::runtime_error chyby zpsoben okolnm prostedm
nap. nedostatek pamti (bad_alloc)
v konstruktoru meme specifikovat dvod (std::string)
http://www.cplusplus.com/reference/std/stdexcept/

STL algs, Vjimky, Functor 3.11.2014
32
PB161
new a zachycen vjimky

STL algs, Vjimky, Functor 3.11.2014
33
// Allocate A object dynamically
// If fail, std::bad_alloc exception is thrown
A* pTest2 = 0;
try {
pTest2 = new A(20);
pTest2->print(); // no need to test pTest2 != NULL
delete pTest2;
}
catch (std::bad_alloc& ex) {
cout << "Fail to allocate memory";
}
class A {
int m_value;
public:
A(int value) : m_value(value) {}
void print() const {cout << m_value << endl; }
};
PB161
Vlastn vjimky - tdy
STL algs, Vjimky, Functor 3.11.2014
std::exception nem konstruktor s monost specifikace dvodu
(etzec)
Ddme typicky z logic_error a runtime_error
maj konstruktor s parametrem dvodu (std::string)
Nebo jejich specifitjch potomk
nap. std::invalid_argument pro chybn argumenty
34
http://www.cplusplus.com/reference/std/stdexcept/
PB161
Vlastn vjimky - ukzka

STL algs, Vjimky, Functor 3.11.2014
35
class WrongNameExceptionExt : public std::invalid_argument {
std::string m_wrongName;
public:
WrongNameExceptionExt(const std::string& reason = "", const std::string name = "") :
std::invalid_argument(reason), m_wrongName(name) {}
const std::string getName() const { return m_wrongName; }
~WrongNameExceptionExt() throw () {}
};
Jmno vjimky
rodi vjimky
zvolte co
nejspecifitji
Vjimka me nst
dodaten informace dle
naich poteb
Konstruktor pro specifikace
informac o vjimce.
Inicializuje i pedka.
Meme pidat vlastn
dodaten metody
Destruktor nutn pokud
mme atributy, kter maj
tak destruktor
PB161
Zachycen vjimek vyuit ddinosti
Vjimky mohou tvoit objektovou hierachii
typicky njac potomci std::exception
Pi zachytvn meme zachytvat rodiovsk
typ
nemusme chytat vjimky podle nejspecifitjho typu
obslun kd me reagovat na celou tdu vjimek
nap. zachytv vjimku typu std::runtime_error a vechny
potomky
STL algs, Vjimky, Functor 3.11.2014
36
class MyException : public std::invalid_argument;

int main() {
try {
throw MyException(Test);
}
catch (std::invalid_argument& ex) {
cout << invalid argument : " << ex.what();
}
return 0;
}
Vyvolme MyException,
chytme
invalid_argument
PB161
Poad vyhodnocovn catch klauzul
Dle poad v kdu
pokud je vce klauzul, postupn se hled klauzule s
odpovdajcm datovm typem
klauzule ve budou vyhodnoceny dve
Vhodn adit od nejspecifitj po nejobecnj
nejprve potomci, potom pedci
jinak se pozdj specifitj nikdy neuplatn
Kompiltor ns upozorn warningem
warning: exception of type 'WrongNameException' will
be caught by earlier handler for 'std::logic_error'

STL algs, Vjimky, Functor 3.11.2014
37
PB161
Poad zachycen ukzka problmu


STL algs, Vjimky, Functor 3.11.2014
38
class WrongNameExceptionExt : public std::invalid_argument;

class Person;

int main() {
cout << "Code before exception handling" << endl;
try {
Person p2(""); // Exception WrongNameExceptionExt thrown
}
catch (std::invalid_argument& ex) {
cout << "Exception from group std::logic_error : " << ex.what();
}
catch (WrongNameExceptionExt& ex) {
cout << "WrongNameExceptionExt: " << ex.what() << " " << ex.getName();
}

cout << "Continuing after block with exception handling" << endl;

return 0;
}
Nen nikdy provedeno vechny
vjimky WrongNameExceptionExt jsou
zachyceny jako std::invalid_argument
PB161
Zachycen a znovuposln vjimky
Nkdy zjistme e ji nedokeme obslouit
nebo chceme jet provst obsluhu jinde
Vjimka typicky zanik na konci bloku catch,
kter ji zachyt
pokud neurme jinak
Vjimku meme poslat dl
do bloku catch umstme throw bez argument
pole dl aktuln vjimku

STL algs, Vjimky, Functor 3.11.2014
39
PB161
Znovuposln vjimky - ukzka

STL algs, Vjimky, Functor 3.11.2014
40
class WrongNameExceptionExt : public std::invalid_argument;
class Person;

void foo() {
try {
Person p1("Pepa Novak"); // No problem
Person p2(""); // Exception thrown
}
catch (WrongNameExceptionExt& ex) {
cout << "WrongNameExceptionExt: " << ex.what() << endl;
throw; // Let it propagate further
}
}
int main() {
try {
foo();
}
catch (std::logic_error& ex) {
cout << "Exception std::logic_error : " << ex.what();
}
return 0;
}
Vjimka odchycena,
ale poslna dl
Vjimka znovu
zachycena a finln
zpracovna.
Przdn jmno zpsob
vjimku
PB161
Zachycen vech vjimek catch()
Klauzule catch(){} zachyt vtinu bnch
vjimek
zvis na pekladai, nkdy i nezotaviteln jako
SIGSEGV (VS6)
nen pstup k objektu vjimky
V bnm kdu zachytvejte pouze vjimky, kter
umte zpracovat
pokud opravdu nevte e potebujete zachytit vechny
okoln kd me bt schopen na vjimku reagovat lpe
STL algs, Vjimky, Functor 3.11.2014
41
PB161
Zachycen vech vjimek catch()
V nkterch ppadech je naopak velmi vhodn
zachytvat vechny vjimky
vjimky by nemly bt propagovny mimo v modul
nen dna pesn realizace objektu vjimky, zle na pekladai
kd peloen jinm me spadnout pi oeten
Obalen tla funkce main()
zabrn nezenmu pdu programu
Obalen tla destruktoru
destruktor by neml nikdy vyvolat vjimku (kdo by oetil?)
Obalen tla callback funkce
vjimka z na callback funkce jde do kontextu uivatele callbacku
STL algs, Vjimky, Functor 3.11.2014
42
PB161
catch() pro logovn
Vyuv se nap. v kombinaci se znovuvyvolnm
pro uloen logu o problmu

STL algs, Vjimky, Functor 3.11.2014
43
int main() {
try {
foo();
}
catch (...) {
cerr << "error in " << __FILE__ << __LINE__;
throw;
}
return 0;
}
PB161
Nezachycen vjimka
STL algs, Vjimky, Functor 3.11.2014
Me nastat kdy
neobsluhujeme vjimky vbec
nastane mimo blok s obsluhou vjimky
Nsleduje ukonen programu
44
#include <stdexcept>

int main() {
// 1. Segmentation fault (SIGSEGV)
int array[10];
array[100] = 1;

// 2. Division by zero (SIGFPE)
float result = 10 / 0;



// 3. Own uncoght exception
throw std::logic_error("Test");
return 0;
}
PB161
Seznam vyvolvanch vjimek
Meme specifikovat seznam vjimek, kter dan metoda
me vyvolat (exception-specification)
informace pro uivatele metody (co hldat a zkouet odchytvat)
informace pro peklada (mon optimalizace, ale viz. dle)
Pokud metoda vyvol jinou vjimku ne deklarovanou
je zavolna funkce std::unexpected()
defaultn implementace peru program
meme upravit set_unexpected(nae_obslun_fce)
Pozor na odlinost od Javy!
u Javy kontroluje peklada (nedovol vyvolvat jinou vjimku)
u C++ kontroluje a bhov prosted (pomoc unexpected())
Problematick, spe nepouvejte
viz. diskuze http://www.gotw.ca/publications/mill22.htm
vvoje nekontroluje (a za bhu), pekladai tm nepomh
STL algs, Vjimky, Functor 3.11.2014
45
PB161
Seznam vyvolvanch vjimek - ukzka

STL algs, Vjimky, Functor 3.11.2014
46
struct MyStructException;
class MyException : public std::invalid_argument;

void foo(int what) throw(int, MyException) {
if (what == 1) throw 1;
if (what == 2) throw 'e';
if (what == 3) {
MyStructException ex;
ex.reason = "Just testing";
ex.someValue = -1;
throw ex;
}
if (what == 4) throw MyException("Just testing");
}

// Note: will compile even when foo()
// has different exception-specification
void foo2(int what) throw(int) {
foo(what);
}

void handleUnexpected () {
std::cerr << "unexpected exception thrown";
// throws exception with int type
//(allowed in exception-specification)
throw -1;
// ... or e.g., terminate
//std::terminate();
}
#include <iostream>
#include <stdexcept>
#include <string>
using std::cout;
using std::endl;

int main() {
std::set_unexpected(handleUnexpected);

cout << "Code before exception handling" << endl;

try {
foo2(3); // throw MyStructException

cout << "Will not be printed";
}
catch (int ex) {
cout << "Integer exception: " << ex << endl;
}
catch (MyStructException& ex) {
cout << "Struct exception : " << ex.reason;
}

cout << "Continuing after block with EH";

// We may reset unexpected handler to default
std::set_unexpected(std::terminate);

return 0;
}
PB161
Vhodnost pouit opakovan obsluha chyb
Vjimky mohou vrazn omezit podmnn kd
pro obsluhu chyby
kd s podmnkami obsahuje nejastji chybu
vjimky omezuj mnostv kdu s podmnkami
mus vak bt pouvny sprvn (viz. zneuvn)
Pi pouit vjimek nemusme mt kd pro
vyhodnocen a pedn chyby v kad funkci


STL algs, Vjimky, Functor 3.11.2014
47
PB161
Vhodnost pouit vjimek - konstruktory
Chybu v konstruktoru nelze pedat nvratovou
hodnotou
dn nen
typicky chybn argumenty
Lze eit njakou validan metodou isValid()
me bt nepohodln
musme testovat kad vytven objekt
Pi chyb v konstruktoru lze vyhodit vjimku
viz. przdn jmno u tdy Person
typicky instance std::invalid_argument nebo jej potomek
throw std::invalid_argument(Invalid empty name);
STL algs, Vjimky, Functor 3.11.2014
48
PB161
Vhodnost pouit vjimek - opertory
Chyby pi pouit opertor
opertory typicky nevrac chybov status
nvratov hodnota opertoru nemus bt pouiteln
nap. opertor stn me zpsobit peteen vsledku
Nkter opertory nastavuj fail bit
nap. >> a << pro iostream
me bt nutn testovat po kad operaci - nepraktick
Pi chyb v opertoru lze vyhodit vjimku
nap. pi detekci peteen u stn
throw std::overflow_error(+ result overflow);
STL algs, Vjimky, Functor 3.11.2014
49
PB161
Vjimky pro I/O opertory

STL algs, Vjimky, Functor 3.11.2014
50
#include <iostream>

int main() {
std::cin.exceptions( std::istream::failbit);
try {
int i;
std::cin >> i;
std::cout << "Succesfully read: " << i << std::endl;
}
catch (std::istream::failure & ex) {
std::cout << "Exception: " << e.what() << std::endl;
}

return 0;
}

int x;
cin >> x;
if (cin.fail()) { }
PB161
(Ne)vhodnost pouit vjimek dealokace
Vjimka me zpsobit memory leak
kd s dealokac dky vjimce neprobhne
Lze eit kombinac zachycen a znovuvyputn
catch () { delete[] data; throw; }
Lze eit pouitm auto_ptr,unique_ptr
vhodnj, meme deklarovat i alokovat v podblocch


STL algs, Vjimky, Functor 3.11.2014
51
PB161
Zneuvn a naduvn vjimek
STL algs, Vjimky, Functor 3.11.2014
Zachytvn, ale neoetovn vjimek
catch () { /* do nothing */ }
zachytme ve a nereagujeme
Naduvn vjimek
nap. nadmrn testovn pstupu k poli pomoc at()

52
std::vector<int> myVect(100, 5);
float result = 0;

for (unsigned int i = 0; i < 10000000; i++) {
if (i < myVect.size()) result += myVect[i];
}
for (unsigned int i = 0; i < 10000000; i++) {
try {
result += myVect.at(i);
}
catch (std::out_of_range& ex) {
// do nothing
}
}
bez vjimky
s vjimkou
PB161
Problm s defaultnm destruktorem
Me nastat pi vytven vlastn vjimky jako
potomek exception
error: looser throw specifier for
pozor, ne vechny pekladae hls
Nastv, pokud u tdy vjimky definujeme
atributy s vlastnm destruktorem
nap. std::string pro uloen dalch informac
atribut me zpsobit vyvoln vjimky, kterou pedek v throw
deklaraci nespecifikuje
Vce viz.
http://www.agapow.net/programming/cpp/looser-
throw-specifier
STL algs, Vjimky, Functor 3.11.2014
53
PB161
Dal informace k vjimkm
Motivace a pravidla pro vhodnost pouit vjimek
http://www.parashift.com/c++-faq-lite/exceptions.html
Princip vjimek a vhodnost (nap. RAII)
http://www.gamedev.net/reference/articles/article953.a
sp


STL algs, Vjimky, Functor 3.11.2014
54
PB161
Standardn vjimky
bad_alloc pi dynamick alokaci (typicky
nedostatek pamti)
bad_cast chybn petypovn
bad_exception vyvolan vjimka nen v
seznamu deklarovanch vjimek
bad_typeid vjimka vyvolan funkc typeid
ios_base::failure problm

STL algs, Vjimky, Functor 3.11.2014
55
PB161
Vjimky - ukzky
exceptionTypeDemo.cpp
zachycen vjimek rznch typ
exceptionDemo.cpp
zachycen obecnj vjimky ped specifitj (chyba)
exceptionReThrowDemo.cpp
ukzka znovuvyvoln vjimky
unhandledException.cpp
ukzka neoeten vjimky
exceptionSpeedDemo.cpp
ukzka naduvn vjimek
exceptionSpecifDemo.cpp
ukzka pouit specifikace vyvolvanch vjimek

STL algs, Vjimky, Functor 3.11.2014
56
PB161
Shrnut
STL Algoritmy
Velk mnostv pedpipravench operac nad
kontejnery a iteartory
Functor
Objekt vyuiteln namsto funknho ukazatele
Vjimky jsou nstroj pro usnadnn oeten chyb
Spolen msto pro oeten vjimek z vtho rozsahu
kdu
Lze vyut ddinosti
Pozor na naduvn vjimek

STL algs, Vjimky, Functor 3.11.2014
57
PB161
Bonus

STL algs, Vjimky, Functor 3.11.2014

You might also like