Elektrotehnicki fakultet, Beograd  Ласло Краус ИР2ОО1
Други колоквијум
11. 2. 2007.

Аутори: Игор Тартаља, Ђорђе Ђурђевић и Ласло Краус

Задаци: 1 2 | Напоменe | Решења: 2

Поставка задатка 1 (30 поена) ( почетак)

Одговорити концизно (једна или две реченице) и прецизно на следећа питaња:

а) Да ли се преко објекта заштићено изведене класе може приступити јавном члану основне класе и зашто?

б) Шта се дешава када се у некој catch грани изврши наредба throw; ?

в) Шта се назива делимичном, а шта потпуном специјализацијом шаблона? Навести декларације као примере обе специјализације шаблона template <class T1, class T2> class S;

Поставка задатка 2 (укупно 70 поена) ( решење | почетак)

Коришћењем приложених готових класа за графичко приказивање текстова (Симбол описује особине једног знака. Фонт садржи скуп симбола за једну врсту знакова. Вектор означава положај у равни), написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа једноставних класа):


Напоменe ( почетак)


Решење задатка 2 ( поставка | почетак)

#include <iostream>
#include <cstring>
using namespace std;

/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
class Simbol {                                                     //
  char zn;                                                         //
  double odnos;                                                    //
public:                                                            //
  Simbol(char z,double odn){zn=z; odnos=odn;}                      //
  char znak () const { return zn; }                                //
  double sirina (double vis) const { return vis * odnos; }         //
};                                                                 //
                                                                   //
class GNema {};                                                    //
                                                                   //
class Font {                                                       //
  struct Elem {                                                    //
    Simbol sim; Elem* sled;                                        //
    Elem (const Simbol& s): sim(s) {sled=0;}                       //
  };                                                               //
  Elem *prvi, *posl;                                               //
  int duz;                                                         //
  void kopiraj (const Font& f);                                    //
  void brisi ();                                                   //
public:                                                            //
  Font () { prvi = posl = 0; duz = 0; }                            //
  Font (const Font& f) { kopiraj (f); }                            //
  ~Font () { brisi (); }                                           //
  Font& operator= (const Font& f) {                                //
    if (this != &f) { brisi(); kopiraj(f); }                       //
    return *this;                                                  //
  }                                                                //
  int duzina () const { return duz; }                              //
  Simbol& operator[] (char zn);                                    //
  const Simbol& operator[] (char zn) const                         //
    { return const_cast<Font&>(*this)[zn]; }                       //
  Font& operator+= (const Simbol& s) {                             //
    try {                                                          //
      (*this)[s.znak()] = s;                                       //
    } catch (GNema) {                                              //
      duz++;                                                       //
      posl = (!prvi ? prvi : posl->sled) = new Elem (s);           //
    }                                                              //
    return *this;                                                  //
  }                                                                //
};                                                                 //
                                                                   //
void Font::kopiraj (const Font& f) {                               //
  prvi = posl = 0; duz = f.duz;                                    //
  Elem *tek = prvi, *pret = 0;                                     //
  for (Elem *tek=f.prvi; tek; tek=tek->sled)                       //
    posl = (!prvi ? prvi : posl->sled) = new Elem (tek->sim)       //
}                                                                  //
                                                                   //
void Font::brisi () {                                              //
  while (prvi) {                                                   //
    Elem* stari = prvi; prvi = prvi->sled; delete stari;           //
  }                                                                //
}                                                                  //
                                                                   //
Simbol& Font::operator[] (char zn) {                               //
  for (Elem* tek=prvi; tek; tek=tek->sled)                         //
    if (tek->sim.znak() == zn) return tek->sim;                    //
  throw GNema ();                                                  //
}                                                                  //
                                                                   //
class Vektor {                                                     //
  double x, y;                                                     //
public:                                                            //
  Vektor (double a=0, double b=0) {x=a; y=b;}                      //
  Vektor& operator+= (const Vektor& v)                             //
    { x += v.x; y += v.y; return *this; }                          //
  friend ostream& operator<< (ostream& it, const Vektor& v)        //
    { return it<<'('<<v.x<<','<<v.y<<')'; }                        //
};                                                                 //
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////

class Figura {
public:
  virtual ~Figura () {}
  virtual Figura& operator+= (const Vektor& v) =0;
  virtual Figura* kopija () const =0;
private:
  virtual void pisi (ostream& it) const =0;
  friend ostream& operator<< (ostream& it, const Figura& f)
    { f.pisi (it); return it; }
};

class Duz: public Figura {
  Vektor A, B;
  void pisi (ostream& it) const { it << A << '-' << B; }
public:
  Duz (const Vektor& P, const Vektor& Q): A(P), B(Q) {}
  Duz& operator+= (const Vektor& v)
    { A += v; B += v; return *this; }
  Duz* kopija()const {return new Duz(*this);}
};

class Tekst: public Figura {
  char* niz;
  double vis; Font fnt; Vektor poz;
  void pisi (ostream& it) const {
    it << niz << '[' << poz << ','
       << vis << ',' << sirina() << ']';
  }
public:
  Tekst (const char* tks, double h, const Font& f,
         const Vektor& p): fnt(f), poz(p) {
    niz=strcpy(new char[strlen(tks)+1],tks);
    vis = h;
  }
  Tekst (const Tekst& t): fnt(t.fnt), poz(t.poz) {
    niz = strcpy (new char [strlen(t.niz)+1], t.niz);
    vis = t.vis;
  }
  ~Tekst () { delete [] niz; }
  Tekst& operator= (const Tekst& t) {
    if (this != &t) {
      niz = strcpy (new char [strlen(t.niz)+1], t.niz);
      vis = t.vis; fnt = t.fnt; poz = t.poz;
    }
  }
  double visina () const { return vis; }
  double sirina () const;

  Tekst& operator+= (const Vektor& v) { poz += v; return *this; }
  Tekst* kopija () const { return new Tekst (*this); }
};

double Tekst::sirina () const {
  double s = 0;
  for (unsigned i=0; i<strlen(niz); s+=fnt[niz[i++]].sirina(vis));
  return s;
}

class GPun {};
class GIndeks {};
class GPrazno {};

template <class T>
class Niz {
  T** niz; int kap;
  void kopiraj (const Niz& n);
  void brisi ();
public:
  explicit Niz (int k=10);
  Niz (const Niz& n) { kopiraj (n); }
  ~Niz () { brisi (); }
  Niz& operator= (const Niz& n) {
    if (this != &n) { brisi(); kopiraj(n); }
    return *this;
  }
  int kapac () const { return kap; }
  Niz& operator+= (const T& t);
  Niz& izbaci (int i) {
    if (i>=0 && i<kap) { delete niz[i]; niz[i] = 0; }
    return *this;
  }
  T& operator[] (int i) {
    if (i<0 || i>=kap) throw GIndeks ();
    if (! niz[i]) throw GPrazno ();
    return *niz[i];
  }
  const T& operator[] (int i) const {
    if (i<0 || i>=kap) throw GIndeks ();
    if (! niz[i]) throw GPrazno ();
    return *niz[i];
  }
  template <class T>
  friend ostream& operator<< (ostream& it, const Niz<T>& n);
};

template <class T>
void Niz<T>::kopiraj (const Niz& n) {
  niz = new T* [kap = n.kap];
  for (int i=0; i<kap; i++)
    niz[i] = n.niz[i] ? n.niz[i]->kopija() : 0;
}

template <class T>
void Niz<T>::brisi () {
  for (int i=0; i<kap; delete niz[i++]);
  delete [] niz;
}


template <class T>
Niz<T>::Niz (int k) {
  niz = new T* [kap = k];
  for (int i=0; i<k; niz[i++]=0);
}

template <class T>
Niz<T>& Niz<T>::operator+= (const T& t) {
  int i = 0; while (i<kap && niz[i]) i++;
  if (i == kap) throw GPun ();
  niz[i] = t.kopija ();
  return *this;
}

template <class T>
ostream& operator<< (ostream& it, const Niz<T>& n) {
  it << '<';
  for (int i=0; i<n.kap; i++) {
    if (i) it << " # ";
    if (n.niz[i]) it << *n.niz[i];
  }
  return it << '>';
}

class Crtez: public Figura {
  Niz<Figura> niz;
  void pisi (ostream& it) const { it << niz; }
public:
  explicit Crtez (int kap): niz(kap) {}
  Crtez& operator+= (const Figura& f) { niz += f; return *this;}
  Crtez& operator+= (const Vektor& v);
  Crtez* kopija () const { return new Crtez (*this); }
};

Crtez& Crtez::operator+= (const Vektor& v) {
  for (int i=0; i<niz.kapac(); i++)
    try { niz[i] += v; } catch (GPrazno) {}
  return *this;
}

/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
int main () {                                                      //
  Font fnt;                                                        //
  fnt += Simbol ('m',0.8);                                         //
  fnt += Simbol ('a', 0.5);                                        //
  fnt += Simbol ('!', 0.1);                                        //
  Crtez crt (2);                                                   //
  crt += Duz (Vektor(1,1),Vektor(2,3));                            //
  crt += Tekst ("mama!",1,fnt,Vektor(2,1));                        //
  cout << crt << endl;                                             //
  crt += Vektor (2, 1); crt *= 2;                                  //
  cout << crt << endl;                                             //
  return 0;                                                        //
}                                                                  //
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////

<(1,1)-(2,3) # mama![(2,1),1,2.7]> <(3,2)-(4,4) # mama![(4,2),1,2.7]>
( почетак)
         
Аутор: Ласло Краус
Е-пошта: kraus@etf.rs

Copyright © 2010, Laslo Kraus
Последња ревизија: 30.8.2010.