Wykład 9 - powtórzenie. 11 maja 2007
Powtórzenie materiału obiekty automatyczne, statyczne, tymczasowe, dynamiczne dziedziczenie, agregacja polimorfizm, funkcje wirtualne wzorce projektowe (strukturalne, bechawioralne, kreacyjne) obsługa błędów, mechamizm wyjątków sprytne wskaźniki szablony biblioteka standardowa, kolekcje
Zad 1 - szablony Napisz szablon funkcji wypisującej elementy kolekcji na podany strumień. Elementy rozdzielaj przecinkiem. template<typename T> void print(const T& kolekcja, std::ostream& os) { /* tutaj implementacja */ Które instrukcje tworzą iterator (wewnątrz szablonu print): T::const_iterator it; typename T::const_iterator it; class T::const_iterator it; Podaj prawidłowe konkretyzacje szablonu print: vector<int> v; print(v, cout); vector<int> v; print<int>(v, cout); vector<int> v; print<std::vector<int> >(v, cout);
Zad 2 - wyjątki Podaj napis, który będzie wypisany po wywołaniu funkcji zad2(). //Klasa wyjatku struct E : public std::exception { char c_; E(char c) : c_(c) { ; //Klasa wyjatku struct EE : public E { EE(char c) : E(c) { ; struct Foo { char c_; Foo(char c) : c_(c) { cout << c_; Foo(){ cout << c_; ; typedef std::auto_ptr<foo> PFoo; //Metoda fabryczna PFoo f(char c){ return PFoo(new Foo(c) );
void g() { PFoo pa = f( a ); { PFoo pb = f( b ); try { PFoo pc = pa; throw EE( c ); f( d ); catch(const E&) { cout << e ; throw EE( f ); catch(const EE&) { cout << g ; throw E( h ); void zad2() { try { g(); catch(const EE&) { cout << i ; catch(const E&) { cout << j ; cout << endl;
Zad 3 - wzorce Uzupełnij implementacje klas Pracownik, Specjalista, Kierownik aby możliwe było tworzenie kopii obiektów tych klas. void zad3() { Kierownik* k = new Kierownik( Abacki ); k->dodaj( new Pracownik( Babacki ) ); k->dodaj( new Pracownik( Cabacki ) ); Kierownik* kk = new Kierownik( Dabacki ); kk->dodaj( k ); kk->dodaj( new Specjalista( Ebacki ) ); //tutaj tworzy kopie obiektu Kierownik* kkk = new Kierownik(*kk); delete kk; /* tutaj posluguje sie obiektem kkk */ delete kkk;
struct Pracownik { virtual Pracownik() { ; struct Specjalista : public Pracownik { virtual Specjalista() { ; class Kierownik : public Pracownik { public: Kierownik(const std::string& n) : Pracownik(n) { virtual Kierownik() { for(vector<pracownik*>::iterator it= podlegli.begin(); it!= podlegli.end(); ++it ) delete *it; void dodaj(pracownik* prac) { podlegli.push_back(prac); private: vector<pracownik*> podlegli; ;
zad4 - stl, kolekcje zaproponuje kolekcję przechowującą dane personalne (imię, nazwisko, adres). Najczęstszą operacją na kolekcji jest wyszukiwanie informacji bazując na nazwisku. zaproponuj kolekcję przechowującą kolejkę zadań do wykonania (zadanie jest opisane przez nazwę oraz opis). Elementy są dodawane na koniec, zaś usuwany jest początkowy.
zad5 - różne Odziedziczyłeś projekt, który zawiera klasę Zespolone. class Zespolone { public: Zespolone( double re, double im = 0 ) : re_(re), im_(im) {; void operator+( Complex other ) { _re = _re + other._real; _im = _im + other._imaginary; void operator<<( std::ostream os ) { os << ( << _re <<, << _im << ) ; Zespolone operator++() { ++_re; return *this; private: double re_, im_; ;
Operator przypisania Dla klasy Okno dostarczono trzy warianty operatora przypisania: class Bitmap { /*... */ ; class Okno { /*... */ private: Bitmap* b; ; Które warianty zapewniają bezpieczne przypisanie obiektu samego do siebie? Które warianty zostawią obiekt w poprawnym stanie, zakładając, że konstruktor Bitmap zgłosi wyjątek? Która implementacja operatora przypisania jest najlepsza dla klasy Okno(uzasadnij)?
//Implementacja 1 Okno& operator=(const Okno& o) { delete b; b = new Bitmap(*o.b); return *this; //Implementacja 2 Okno& operator=(const Okno& o) { if(this == &o) return *this; delete b; b = new Bitmap(*o.b); return *this; //Implementacja 3 Okno& operator=(const Okno& o) { Bitmap* old = b; b = new Bitmap(*o.b); delete old; return *this;