//: C01:Wrapped.cpp
// Z knihy "Myslíme v jazyce C++, část 2" od Bruce Eckela a Chucka Allisona.
// (c) 1995-2004 MindView, Inc. Všechna práva vyhrazena.
// Přečtěte si podmínky používání zdrojových kódů umístěné v souboru 
// 'Licence.txt' dodávaném spolu s balíčkem kódu dostupným na www.MindView.net.
// bezpečné, základní ukazatele.
#include <iostream>
#include <cstddef>
using namespace std;

// Zjednodušeno. Vaše šablona může mít další parametry
template<class T, int sz = 1> class PWrap {
  T* ptr;
public:
  class ChybaRozsahu {}; // třída výjimky
  PWrap() {
    ptr = new T[sz];
    cout << "konstruktor PWrap" << endl;
  }
  ~PWrap() {
    delete[] ptr;
    cout << "destruktor PWrap" << endl;
  }
  T& operator[](int i) throw(ChybaRozsahu) {
    if(i >= 0 && i < sz) return ptr[i];
    throw ChybaRozsahu();
  }
};

class Kocka {
public:
  Kocka() { cout << "Kocka()" << endl; }
  ~Kocka() { cout << "~Kocka()" << endl; }
  void g() {}
};

class Pes {
public:
  void* operator new[](size_t) {
    cout << "Vytváří se Pes" << endl;
    throw 47;
  }
  void operator delete[](void* p) {
    cout << "Ruší se Pes" << endl;
    ::operator delete[](p);
  }
};

class PouzijZdroje {
  PWrap<Kocka, 3> kocky;
  PWrap<Pes> pes;
public:
  PouzijZdroje() { cout << "PouzijZdroje()" << endl; }
  ~PouzijZdroje() { cout << "~PouzijZdroje()" << endl; }
  void f() { kocky[1].g(); }
};

int main() {
  try {
    PouzijZdroje pz;
  } catch(int) {
    cout << "uvnitř správce" << endl;
  } catch(...) {
    cout << "uvnitř catch(...)" << endl;
  }
} ///:~
