Ласло Краус |
ИР2ОО1/СИ2ОО1 Испит 25. 1. 2009. |
---|
Одговорити концизно (једна или две реченице) и прецизно на следећа питaња:
а) Да ли се контрола права приступа члановима класе остварује у језику C++ на нивоу појединачних објеката или на нивоу свих објеката једне класе?
б) Којим редоследом треба навести руковаоце изузецима (catch
гране) ако се жели обрада изузетака (1) потпуно произвољног типа, (2) изузетака основне класе А
изведене из класе стандардних изузетака exception
, (3) изузетака класе B
изведене из класе A
и (4) изузетака класе exception
?
в) Зашто се шаблони (templates) по правилу смештају у датотеке заглавља (.h
) и шта је недостатак таквог поступка?
Написати на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа једноставних класа које су опремљене писањем текста поруке):
it<<saobracajnica
, пише се име саобраћајнице и дужина у загради). Име и дужина се задају приликом стварања, али име може и накнадно да се мења.
it<<zgrada
, пише се површина/
број_спратова/
број_стамбених_јединица).
zbr[kljuc]
) (грешка је ако не постоји елемент који одговара задатом кључу). Није дозвољено користити класе из стандардне библиотеке шаблона (STL).
it<<naselje
, пише се назив[
укупан_број_зграда]
).
#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; }(⇒ почетак)
Copyright © 2010, Laslo Kraus
Последња ревизија: 30.8.2010.