Zestaw 3
Transkrypt
Zestaw 3
Imię i nazwisko: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . czas: 60 min Zadanie 1 (6pkt) Napisz szablon funkcji wypisującej elementy kolekcji na podany strumień. Elementy rozdzielaj spacją. template<typename T> void print(const T& kolekcja, std::ostream& os) { } Które instrukcje (wewnątrz szablonu print) tworzą obiekt iteratora? a) typename T::const_iterator it; b) T::const_iterator it; c) class T::const_iterator it; Które a) b) c) konkretyzacje szablonu print są prawidłowe? std::list<int> l; print(l, std::cout); std::list<int> l; print<std::list<int> >(l, std::cout); std::list<int> l; print<int>(l, std::cout); Zadanie 2(9pkt) Klasy File oraz Dir reprezentują plik oraz katalog. Przykład użycia to test1. Implementacja uniemożliwia reprezentację drzewiastych struktur (katalog zawiera inny katalog). Zaproponuj odpowiednie modyfikacje w kodzie, tak to było możliwe, tzn. aby test2 wykonywał się poprawnie. //test1 Dir* f = new Dir(¨Folder¨); f->add( new File(¨File1¨,10) ); f->add( new File(¨File2¨,30) ); f->add( new File(¨File3¨,50) ); assert( f->getSize() == 90 ); delete f; class File { public: File(std::string n, int s) : name_(n), size_(s) {} std::string getName() const { return name_; } int getSize() const { return size_; } ˜File(){} private: std::string name_; int size_; }; class Dir { typedef File* Child; typedef std::vector<Child> Children; public: Dir(const std::string& n) : name_(n) {} std::string getName() const { return name_; } int getSize() const { int size = 0; for(Children::const_iterator i= ch_.begin(); i != ch_.end(); ++i ) size += (*i)->getSize(); return size; } void add(Child el) { ch_.push_back(el); } ˜Dir() { for(Children::iterator i = ch_.begin(); i != ch_.end(); ++i ) delete *i; } private: std::string name_; Children ch_; }; //test2 Dir* h = new Dir(¨Filder¨); h->add( new File(¨File1¨,50) ); Dir* g = new Dir(¨SubFolder¨); g->add( new File(¨File2¨,10) ); g->add( new File(¨File3¨,30) ); h->add(g); assert( h->getSize() == 90 ); delete h; Zadanie 3(6pkt) Podać napis, który zostanie wydrukowany po wywołaniu następującego kodu: try { h(); } catch(const std::exception&) { std::cout << ’c’; } catch(const E& e) { std::cout << e.c_; } Ile razy zostanie wywołany destruktor klasy X Jeżeli definicja typu PX zostanie zmieniona na następującą: typedef X* PX;, to ile razy zostanie wywołany destruktor klasy X struct E : public std::exception { char c_; E(char c) : c_(c) {} }; struct X { char c_; X(char c) : c_(c) { std::cout << c_; } ˜X(){ std::cout << c_; } }; typedef std::auto_ptr<X> PX; PX f(char c){ return PX(new X(c) ); } void g(PX px){ throw E(px->c_); } void h() { PX pa = f(’a’); try { PX pb = pa; g(f(’b’)); } catch(const E& e) { std::cout « e.c_; throw; } } Zadanie 4(6pkt) Klasa Wekt2D reprezentuje wektor w przestrzeni dwuwymiarowej (zakładamy, że współrzędne są całkowite). Popraw błędy (znajdź min. 12). Przykład użycia jest następujący: Wekt2D w1(1,1), w2(2); assert( w1 + w2 == Wekt2D(3,1) ); class Wekt2D { public: explicit Wekt2D(int dx, int dy = 0) : dx_(dx), dy_(dy) {} int getDX() { return dx_; } int getDY() { return dy_; } Wekt2D& operator+=(const Wekt2D& w) { Wekt2D o; o.dx_ = w.dx_ + dx_; o.dy_ = w.dy_ = dy_; return o; } Wekt2D& operator+(Wekt2D& w) const { Wekt2D o(*this); o += w; return o; } int operator==(Wekt2D w) const { return dy_ == w.dy_; } private: int dx_, dy_; }; std::ostream& operator<<(std::ostream os, const Wekt2D& w) { os << ¨(¨ << w.getDX() << ¨,¨ << w.getDY() << ¨)¨; } Zadanie 5 (3pkt) Podaj zastosowania klasy boost::shared_ptr.