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) class T::const_iterator it;
b) typename T::const_iterator it;
c) T::const_iterator it;
Które konkretyzacje szablonu print są prawidłowe?
a) std::list<int> l; print<std::list<int> >(l, std::cout);
b) std::list<int> l; print<int>(l, std::cout);
c) std::list<int> l; print(l, std::cout);
Zadanie 2(9pkt)
Klasy File oraz Dir reprezentują plik oraz katalog. Przykład użycia to test1.
Implementacja uniemożliwia reprezen- tację drzewiastych struktur (katalog za- wiera inny katalog). Zaproponuj odpo- wiednie modyfikacje w kodzie, tak to było możliwe, tzn. aby test2 wykony- wał 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;
//test2
Dir* g = new Dir(¨SubFolder¨);
g->add( new File(¨File1¨,10) );
g->add( new File(¨File2¨,30) );
Dir* h = new Dir(¨Filder¨);
h->add(g);
h->add( new File(¨File3¨,50) );
assert( h->getSize() == 90 );
delete h;
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_;
};
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 {
g(f(’b’));
PX pb = pa;
}
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łko- wite). 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+(const Wekt2D& w) { Wekt2D o(*this);
o += w;
return o;
}
bool operator==(Wekt2D w) { return dx_ == w.dx_;
} private:
int dx_, dy_;
};
std::ostream operator<<(std::ostream& os, const Wekt2D& w) { os << ¨(¨ << w.getDX() << ¨,¨ << w.getDY() << ¨)¨;
}