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

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

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

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

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

а) Да ли се контрола права приступа члановима класе остварује у језику C++ на нивоу појединачних објеката или на нивоу свих објеката једне класе?

б) Којим редоследом треба навести руковаоце изузецима (catch гране) ако се жели обрада изузетака (1) потпуно произвољног типа, (2) изузетака основне класе А изведене из класе стандардних изузетака exception, (3) изузетака класе B изведене из класе A и (4) изузетака класе exception?

в) Зашто се шаблони (templates) по правилу смештају у датотеке заглавља (.h) и шта је недостатак таквог поступка?

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

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

(10 поена) Написати на језику C++ програм који, читајући податке с главног улаза, направи једно насеље у које дода неколико (2) улица са стамбеним зградама (1-2) и испише насеље на главном излазу.

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


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

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

class Saobracajnica {
  char ime[30];
  double duzina;

public:
  Saobracajnica( const char* i, double d): duzina( d)
    { postaviIme( i); }

  void postaviIme( const char* i) { strcpy( ime, i); }

  const char* dohvatiIme() const { return ime; }

  friend ostream& operator<< (ostream& it, const Saobracajnica& s)
    { return it << s.ime << '(' << s.duzina << ')'; }
};

class GBroj {};
inline ostream& operator<< (ostream& it, const GBroj&)
  { return it << "*** Pogresna broj stanova!"; }

class Zgrada {
  double povrsina;
  int brSpratova;
  int brStanovaPoSpratu;

public:
  Zgrada(double p, int sprat, int stan)
      : povrsina(p), brSpratova(sprat), brStanovaPoSpratu(stan)
    { if (stan <= 0) throw GBroj(); }

  double dohvatiP() const { return povrsina; }

  int dohvatiBrSprat() const { return brSpratova; }

  int dohvatiBrStanovaPoSpratu() const { return brStanovaPoSpratu; }

  int dohvatiBrStanova() const
    { return dohvatiBrSprat() * dohvatiBrStanovaPoSpratu(); }

  double srednjaP() const
    { return dohvatiP() / dohvatiBrStanovaPoSpratu(); }

  friend ostream& operator<< (ostream& it, const Zgrada& z)
    { return it << z.povrsina << "/" << z.brSpratova
                << "/" << z.dohvatiBrStanova(); }
};

class GAdr {};
inline ostream& operator<< (ostream& it, const GAdr&)
  { return it << "*** Pogresna broj zgrade!"; }

class GZgrada {};
inline ostream& operator<< (ostream& it, const GZgrada&)
  { return it << "*** Zgrada vec postoji!"; }

class Ulica : public Saobracajnica {
  Zgrada      **zgrade;
  int         maksAdr;

	Ulica( const Ulica& u): Saobracajnica( u) {}

  void operator= ( const Ulica&) {}

public:
  Ulica(const char* i, double d, int adr);

  ~Ulica();

  void dodajZgradu( Zgrada* z, int adr) {
    if (adr<1 || adr>maksAdr) throw GAdr();
    if (zgrade[adr-1] != 0) throw GZgrada();
    zgrade[adr-1] = z;
  }

  int brZgrada() const;

  double ukupnaP() const;
};

Ulica::Ulica( const char* i, double d, int adr) : Saobracajnica( i, d) {
  zgrade = new Zgrada*[maksAdr = adr];
  for (int i=0; i<maksAdr; zgrade[i++]=0);
}

Ulica::~Ulica() {
  for (int i=0; i<maksAdr; delete zgrade[i++]);
  delete []zgrade;
}

int Ulica::brZgrada() const {
  int rez = 0;
  for (int i=0; i<maksAdr; i++)
     if (zgrade[i]) rez++;
  return rez;
}

double Ulica::ukupnaP() const {
  double rez = 0;
  for (int i=0; i<maksAdr; i++)
    if (zgrade[i])
      rez += zgrade[i]->dohvatiP() * zgrade[i]->dohvatiBrSprat();
  return rez;
}

class GKljuc {};
inline ostream& operator<< (ostream& it, const GKljuc&)
  { return it << "*** Kljuc vec postoji!"; }

class GKap {};
inline ostream& operator<< (ostream& it, const GKap&)
  { return it << "*** Prekoracenje kapaciteta!"; }

template <typename T>
class AsocZbirka {
protected:
  T **podaci;
  char **kljucevi;
  int kap, pop;

  AsocZbirka ( const AsocZbirka&) {}

  void operator= ( const AsocZbirka&) {}

public:
  AsocZbirka( int k) {
    podaci = new T* [kap = k];
    kljucevi = new char* [kap];
    pop = 0;
  }

  virtual ~AsocZbirka();

  void dodaj( T* pod, const char* kljuc);

  int brPod() const { return pop; }

  T* operator[] ( const char* kljuc);

  const T* operator[] ( const char* kljuc) const
    { return (const_cast<AsocZbirka*>(this))->operator[]( kljuc); }

   T* izvadi( const char* kljuc);
};

template<typename T>
AsocZbirka<T>::~AsocZbirka() {
  for(int i = 0; i < pop; i++) {
     delete podaci[i];
     delete kljucevi[i];
  }
  delete []podaci;
  delete []kljucevi;
}

template<typename T>
void AsocZbirka<T>::dodaj( T* pod, const char* kljuc) {
  if (pop==kap) throw GKap();
  for (int i=0; i<pop; i++)
    if (strcmp( kljuc, kljucevi[i]) == 0) throw GKljuc();
  kljucevi[pop] = new char[strlen(kljuc)+1];
  strcpy(kljucevi[pop],kljuc);
  podaci[pop++] = pod;
}

template<typename T>
T* AsocZbirka<T>::operator[] ( const char* kljuc) {
  for (int i=0; i<pop; i++)
    if (strcmp( kljuc, kljucevi[i]) == 0) return kljucevi[i];
  throw GKljuc();
}

class Naselje: public AsocZbirka<Ulica>{
  char* naziv;

public:
  Naselje( const char* n, int kap): AsocZbirka< Ulica>( kap) {
     naziv = new char[strlen(n)+1];
     strcpy(naziv, n);
  }

  ~Naselje() { delete [] naziv; }

  int brZgrada() const;

  friend ostream& operator<< (ostream& it, const Naselje& n);
};

int Naselje::brZgrada() const {
  int brZgrada = 0;
  for (int i=0; i<pop; i++) brZgrada+=podaci[i]->brZgrada();
  return brZgrada;
}

ostream& operator<< ( ostream& it, const Naselje& n)
  { return it << n.naziv << "[" << n.brZgrada() << "]"; }

int main() {
  try {
    Naselje n( "N1", 2);
    Ulica* ul1=new Ulica( "U1", 500, 30);
    Ulica* ul2=new Ulica( "U2", 800, 50);

    ul1->dodajZgradu( new Zgrada( 1200, 6, 4), 2);
    ul1->dodajZgradu( new Zgrada( 1600, 5, 5), 12);
    ul2->dodajZgradu( new Zgrada( 110, 0, 1), 1);
    n.dodaj( ul1, ul1->dohvatiIme());
    n.dodaj( ul2, ul2->dohvatiIme());
    cout << n << endl;
  }
  catch( const GAdr   & g) { cout << g << endl; }
  catch( const GBroj  & g) { cout << g << endl; }
  catch( const GKap   & g) { cout << g << endl; }
  catch( const GKljuc & g) { cout << g << endl; }
  catch( const GZgrada& g) { cout << g << endl; }
  return 0;
}
( почетак)
         
Аутор: Ласло Краус
Е-пошта: kraus@etf.rs

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