Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Bezpieczeństwo wyjątków w C++: OpenGL

Podobne prezentacje


Prezentacja na temat: "Bezpieczeństwo wyjątków w C++: OpenGL"— Zapis prezentacji:

1 Bezpieczeństwo wyjątków w C++: OpenGL
Krzysztof Czaiński Opiekun pracy: dr inż. Cezary Stępień Krzysztof Czaiński

2 Motywacja Dużo literatury o OpenGL
The Red Book (Addison-Wesley)‏ Dobrze opisane bezpieczeństwo wyjątków w C++ Exceptional C++, Herb Sutter OpenGL i wyjątki? GLT ( )‏ Building an OpenGL C++ Class, Dale Rogerson Krzysztof Czaiński

3 Plan prezentacji Dlaczego wyjątki? Bezpieczeństwo wyjątków w C++
Inne sposoby traktowania błędów Bezpieczeństwo wyjątków w C++ Gdzie wstawić bloki try / catch, czy coś więcej? OpenGL, a wyjątki Więcej o bezpieczeństwie wyjątków Krzysztof Czaiński

4 Obsługa błędów, czyli problem komunikacji
Autor klasy (biblioteki) może wykryć błąd, ale nie wie, co z nim zrobić Użytkownik klasy (biblioteki) wie, co zrobić z błędem, lecz nie potrafi go wykryć Przykłąd: Vector, odwołanie do nieistniejącego elementu. Krzysztof Czaiński Źródło: Materiały ZPR dr inż. Robert Nowaka

5 Sposoby traktowania błędów
Wady Ignorowanie Zakończenie programu Komunikat dla użytkownika Kod powrotu Zmienna globalna Specjalny stan obiektu Rezerwacja zwracanej wartości Użytkownik może zignorować błąd Kod obsługi wymieszany z innym kodem Obiekt globalny – potencjalne źródło kłopotów Krzysztof Czaiński Źródło: Materiały ZPR dr inż. Robert Nowaka

6 Mechanizm wyjątków a zasoby
void funkcja()‏ { A* a = NULL; try{a = new A; // Kod rzucający delete a; } catch ( ... )‏ { delete a; throw; } class A {/*...*/}; void funkcja()‏ { A* a = new A; // Kod rzucający delete a; } Niewygodne, nieczytelne, 2xnieefektywne Krzysztof Czaiński

7 Zdobywanie zasobów jest inicjalizacją (RAII)‏
Konstrukcja obiektu jest połączona ze zdobyciem zasobu Destrukcja obiektu jest połączona ze zwolnieniem zasobu Gdy obiekt jest lokalny, zasób jest zwalniany automatycznie w momencie niszczenia obiektu Krzysztof Czaiński

8 Sprytny wskaźnik template< typename X > class AutoPtr { public:
explicit AutoPtr( X* p = NULL ) : p_( p ) {} ~AutoPtr() { delete p_; } X& operator*() const { return *p_; } X* operator->() const { return p_; } private: X* p_; }; Możemy używać jak zwykłego wskaźnika. Uwaga: wszystkie metody throw()‏ Krzysztof Czaiński

9 Użycie sprytnego wskaźnika
class A {/*...*/}; void funkcja()‏ { AutoPtr<A> a( new A ); // Kod rzucający a->metoda(); AutoPtr<A> b = a; // ??? } Co z kopiowaniem? Jak widać, bezpieczeństwo wyjątków jest czymś więcej, niż „gdzie wstawić bloki try/catch. Wręcz „jak unikać bloków try/catch”. Krzysztof Czaiński

10 Przykładowy kod z OpenGL
void render()‏ { double v[3]; glBegin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? glVertex3dv( v ); } glEnd(); Krzysztof Czaiński

11 Automatyczny glBegin/glEnd
#include <boost/utility.hpp> : boost::noncopyable struct Begin { explicit Begin( GLenum mode )‏ glBegin( mode ); } ~Begin()‏ glEnd(); }; Pytanie: jak zrobić niekopiowalność? Krzysztof Czaiński

12 Przykładowy kod z bezpiecznymi wyjątkami
void render()‏ { double v[3]; Begin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? OK. glVertex3dv( v ); } uważać na Begin(); Krzysztof Czaiński

13 Przykładowy kod z bezpiecznymi wyjątkami (2)‏
void render()‏ { double v[3]; Begin begin( GL_TRIANGLES ); for ( int i = 0 ; i < n ; ++i )‏ getVertex( i, v ); // rzuca? OK. glVertex3dv( v ); } Krzysztof Czaiński

14 Zachowanie stanu OpenGL-a
void select()‏ { glRenderMode( GL_SELECT ); // kod rzucający int hits = glRenderMode( GL_RENDER ); //... } Chcemy zagwarantować, żeby po wywołaniu select() OpenGL pozostał w trybie GL_RENDER Krzysztof Czaiński

15 Automatyczny glRenderMode
class RenderMode : boost::noncopyable { public: RenderMode( GLenum mode, GLenum restoreMode )‏ : restoreMode_(restoreMode), restored_(false)‏ { glRenderMode( mode ); } ~RenderMode() { restoreRenderMode(); } GLint restoreRenderMode() { GLint result = 0; if ( ! restored_ ) { restored_ = true; result = glRenderMode( restoreMode_ ); } return result; private: GLenum restoreMode_; bool restored_; }; Krzysztof Czaiński

16 Zachowanie stanu OpenGL-a z auto- glRenderMode
void select()‏ { RenderMode x( GL_SELECT, GL_RENDER ); // kod rzucający int hits = x.restoreRenderMode(); //... } Krzysztof Czaiński

17 Co to znaczy bezpieczeństwo wyjątków?
Gwarancje bezpieczeństwa wyjątków wg Dave’a Abrahama: Podstawowa: Brak wycieku zasobów Wszystkie obiekty pozostają w stanie używalnym, ale nie koniecznie przewidywalnym Silna: Gdy wystąpi wyjątek, stan programu pozostaje niezmieniony Nothrow: Nigdy nie rzuca Czyli po prostu „there are no bugs” - Herb Sutter. Np. Container::AppendElements()‏ global commit-or-rollback semantics Niektóre funkcje muszą zapewniać, aby umożliwić powyższe gwarancje. Np. Destruktory, operacje dealokacji. Operacje auto_ptr są nothrow. Która w przypadku kodu z OpenGL? Krzysztof Czaiński Źródło: GotW #61

18 Korzyści Programowanie bezpieczne z uwzględnieniem wyjątków ma istotne zalety: Użytkownik klasy (biblioteki) może używać mechanizmu wyjątków Wyjątki nie zakłócą pracy programu W razie niespodziewanego błędu (np. braku pamięci) program może działać dalej Wszelkie zasoby zostają zwolnione mimo wyjątku Unikamy nie zwolnienia zasobów przez nieuwagę Zasoby są zwalniane automatycznie . Eclipse i OutOfMemoryException glBeginList i glEnd Krzysztof Czaiński

19 Bezpieczeństwo wyjątków a etap projektowania
template < typename T > class Stack { public: T pop(); // ... private: T* tab_; size_t size_; }; template < typename T > void Stack<T>::pop( T& result )‏ { // assert( size_ > 0 ); result = tab_[size_-1]; --size_; } template < typename T > T Stack<T>::pop()‏ { // assert( size_ > 0 ); T result( tab_[size_-1] ); --size_; return result; } template < typename T > T Stack<T>::pop()‏ { // assert( size_ > 0 ); return tab_[--size_]; } Krzysztof Czaiński

20 Podsumowanie Warto pisać kod w C++ uwzględniając wyjątki i warto uwzględnić to już na etapie projektowania. Dla zainteresowanych polecam: ZPR, dr inż. Robert Nowak 1. Nie jak dokumentacja, dopisywana później. Krzysztof Czaiński


Pobierz ppt "Bezpieczeństwo wyjątków w C++: OpenGL"

Podobne prezentacje


Reklamy Google