Elektrotehnicki fakultet, Beograd  Ласло Краус ИР2ОО1/СИ2ОО1
Испит
16. 1. 2014.

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

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

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

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

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

б) Ако је: class I:public O{…}; и ако је: I i[10]; описати проблем који ће наступити приликом позива m(i); за дефиницију void m(O *o){…o[3]…}. Да ли проблем може да се открије у време превођења и зашто?

в) Aко постоји шаблонска класа template <typename A, typename B> class X{…}; чија имплементација не одговара за замену формалног аргумента (параметра) А стварним аргументом int, написати декларацију шаблонске класе која решава проблем.

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

Написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа једноставних класа које су опремљене писањем текста поруке):

Написати на језику C++ програм који створи магацин, напуни га са неколико поклона и испише га на главном излазу, створи дете и Деда Мраза који формира пакетић за то дете и испише на главном излазу дете, пакетић и завршни садржај магацина. Сви параметри треба да буду константе (не треба ништа учитати).


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


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

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

class Dete {
  char pol; char* ime;
  Dete(const Dete&) {}
  void operator=(const Dete&) {}
public:
  Dete(const char* iime, char ppol) {
    ime = new char [strlen(iime)+1]; strcpy(ime, iime);
    pol = ppol;
  }
  ~Dete() { delete [] ime; }
  const char* dohIme() const { return ime; }
  char dohPol() const { return pol; }
  friend ostream& operator<<(ostream& it, const Dete& d)
    { return it<<d.ime<<':'<<d.pol; }
};

class Poklon {
  static int posId; int id; float cena;
public:
  Poklon(float c) {cena=c; id=++posId;}
  Poklon(const Poklon& p) { cena = p.cena; id = ++posId; }
  virtual ~Poklon() {}
  Poklon& operator=(const Poklon& p) { cena = p.cena; return *this; }
  virtual char dohVrs() const =0;
  virtual char dohPol() const =0;
  virtual float dohCen() const { return cena; }
  virtual Poklon* kopija() const =0;
  friend ostream& operator<< (ostream& it, const Poklon& p)
    { return it << p.dohVrs() << '.' << p.id << '(' << p.cena <<')';}
};

int Poklon::posId = 0;

class Autic: public Poklon {
public:
  Autic(float cena): Poklon(cena) {}
  char dohVrs() const { return 'A'; }
  char dohPol() const { return 'M'; }
  Autic* kopija() const { return new Autic(*this); }
};

class Lutka: public Poklon {
public:
  Lutka(float cena): Poklon(cena) {}
  char dohVrs() const { return 'L'; }
  char dohPol() const { return 'Z'; }
  Lutka* kopija() const { return new Lutka(*this); }
};

class Ukras: public Poklon {
public:
  Ukras(float cena): Poklon(cena) {}
  char dohVrs() const { return 'U'; }
  char dohPol() const { return '?'; }
  Ukras* kopija() const { return new Ukras(*this); }
};

class GPrazna {};
inline ostream& operator<<(ostream& it, const GPrazna&)
  { return it << "*** Zbirka je prazna!";}

template <typename E>
class Zbirka {
  struct Elem {
    E* e; Elem* sled;
    Elem(E *ee) { e = ee; sled = 0; }
  };
  Elem *prvi, *posl; int duz;
  void kopiraj(const Zbirka& z);
  void brisi();
public:
  Zbirka() { prvi = posl = 0; duz = 0; }
  Zbirka(const Zbirka& z) { kopiraj(z);}
  ~Zbirka() { brisi(); }
  Zbirka& operator=(const Zbirka& z) {
    if (this != &z) {brisi(); kopiraj(z);}
    return *this;
  }
  virtual Zbirka& stavi(E* e) {
    posl = (!prvi ? prvi : posl ->s led) = new Elem(e);
    duz++; return *this;
  }
  virtual E* uzmi() {
    if (!prvi) throw GPrazna();
    E* e = prvi->e; Elem* stari = prvi; 
    prvi = prvi->sled; delete stari;
    if (!prvi) posl = 0;
    duz--; return e;
  }
  int brElem() const { return duz; }
  template <typename T>
  friend ostream& operator<< (ostream& it, const Zbirka<T>&z);
};

template <typename E>
void Zbirka<E>::kopiraj(const Zbirka<E>& z) {
  prvi = posl = 0; duz = z.duz;
  for (Elem* tek=z.prvi; tek; tek=tek->sled)
    posl = (!prvi ? prvi : posl->sled) = new Elem(tek->e->kopija());
}

template <typename E>
void Zbirka<E>::brisi() {
  while (prvi) {
    Elem* stari = prvi; prvi=prvi->sled;
    delete stari->e; delete stari;
  }
  posl = 0; duz = 0;
}

template <typename T>
ostream& operator<<(ostream& it, const Zbirka<T>& z) {
  it << '[';
  for (Zbirka<T>::Elem* tek=z.prvi; tek; tek=tek->sled) {
    it<<*tek->e; if (tek->sled) it<<',';
  }
  return it << ']';
}

class Magacin: public Zbirka<Poklon> {
  Magacin(const Magacin&) {};
  void operator=(const Magacin&) {};
public:
  Magacin(): Zbirka<Poklon>() {}
};

class GPol {};
inline ostream& operator<<(ostream& it, const GPol&)
  { return it << "*** Ne odgovara pol!"; }

class GCena {};
inline ostream& operator<<(ostream& it, const GCena&)
  { return it << "*** Previsoka cena!"; }

class Paketic: public Zbirka<Poklon> {
  char pol; float dozv, cen;
public:
  Paketic(char p, float d) { pol = p; dozv = d; cen = 0; }
  Paketic& stavi(Poklon* p) {
    char pl = p->dohPol();
    if (pl!=pol&&pl!='?') throw GPol();
    float cn = p->dohCen();
    if (cen+cn > dozv) throw GCena();
    Zbirka<Poklon>::stavi(p); cen += cn;
    return *this;
  }
  float dohCen() const { return cen; }
  float dohDozv() const { return dozv; }
};

class DedaMraz {
public:
  Paketic* napravi(float max, const Dete& det, Magacin& mag)  {
    char polD = det.dohPol();
    Paketic* pak=new Paketic(polD, max);
    int br = mag.brElem();
    for (int i=0; i<br; i++) {
      Poklon* pok = mag.uzmi();
      char polP = pok->dohPol();
      if ((polP=='?' || polP==polD) && 
           pak->dohCen() + pok->dohCen() <= pak->dohDozv())
        pak->stavi(pok);
      else
        mag.stavi(pok);
    }
    return pak;
  }
};

int main() {
  Magacin mag;
  mag.stavi(new Autic(500));
  mag.stavi(new Lutka(450));
  mag.stavi(new Autic(600));
  mag.stavi(new Ukras(150));
  cout << "M:" << mag << endl;
  Dete dete("Marko",'M');
  Paketic* pak(DedaMraz().napravi(1000,dete,mag));
  cout << "D:" << dete << endl
       << "P:" << *pak << endl 
       << "M:" << mag  << endl;
  delete pak;
}

M:[A.1(500),L.2(450),A.3(600),U.4(150)] D:Marko:M P:[A.1(500),U.4(150)] M:[L.2(450),A.3(600)]
( почетак)
         
Аутор: Ласло Краус
Е-пошта: kraus@etf.rs

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