Ласло Краус |
ИР2ОО1 Други колоквијум 12. 2. 2006. |
|---|
Коришћењем приложених готових класа тачака у равни и географских места чија је контура задата низом тачака у равни, саставити на језику C++ следеће класе (класе опремити оним конструкторима, деструктором и оператором за доделу вредности, који су потребни за безбедно коришћење класа; грешке пријављивати изузецима типа класа које су оспособљене за исписивање текста поруке):
dat<<cvor).
dat<<grana) у облику ozn(poc,kra), где су ozn – ознака гране а poc и kra – ознаке почетног и крајњег чвора гране. Грана не сме да се копира.
niz+=elem; препуњавање низа је грешка). Може да се дохвати број елемената низа и да се приступа елементу са датим редним бројем (niz[ind]; грешка је ако је индекс изван опсега).
Одговорити концизно (по једна или две реченице) и прецизно на следећа питaња:
а) Да ли апстрактна класа може имати атрибуте и конкретне методе и зашто?
б) Шта се дешава са изузетком баченим у неком try блоку уколико иза блока не постоји одговарајућа catch грана која може да обради изузетак?
в) Како се може спречити аутоматско генерисање функције из шаблона за неки тип аргумента?
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
//
class Tacka { //
double xx, yy; //
public: //
Tacka (double x=0, double y=0) { xx = x; yy = y; } //
double x () const { return xx; } //
double y () const { return yy; } //
double rastojanje (Tacka t=Tacka()) //
{ return sqrt (pow(xx-t.xx,2) + pow(yy-t.yy,2)); } //
}; //
//
class Mesto { //
char* iime; Tacka* niz; int n; //
void kopiraj (const Mesto& m); //
void brisi () { delete [] iime; delete [] niz; } //
public: //
explicit Mesto (const char* ime, int nn=8) { //
iime = new char [strlen(ime)+1]; //
strcpy (iime, ime); //
niz = new Tacka [n = nn]; //
} //
Mesto (const Mesto& m) { kopiraj (m); } //
~Mesto () { brisi (); } //
Mesto& operator= (const Mesto& m) { //
if (this != &m) { brisi (); kopiraj (m); } //
return *this; //
} //
Mesto& postavi (Tacka t, int i) { //
if (i>=0 && i<n) niz[i] = t; //
return *this; //
} //
Tacka centar () const; //
double obim () const; //
const char* ime () { return iime; } //
}; //
//
void Mesto::kopiraj (const Mesto& m) { //
iime = new char [strlen (m.iime)+1]; //
strcpy (iime, m.iime); //
niz = new Tacka [n = m.n]; //
for (int i=0; i<n; i++) niz[i] = m.niz[i]; //
} //
//
Tacka Mesto::centar () const { //
double x = 0, y = 0; //
for (int i=0; i<n; i++) { x += niz[i].x(); y += niz[i].y(); } //
return Tacka (x/n, y/n); //
} //
//
double Mesto::obim () const { //
double a = niz[0].rastojanje (niz[n-1]); //
for (int i=1; i<n; i++) a += niz[i-1].rastojanje (niz[i]); //
return a; //
} //
//
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
class Cvor {
char ozn;
virtual void pisi (ostream& d) const { d << ozn; }
public:
explicit Cvor (char oz) { ozn = oz; }
virtual ~Cvor () {}
char oznaka () const { return ozn; }
virtual double vel () const =0;
friend ostream& operator<< (ostream& d, const Cvor& c) { c.pisi (d); return d; }
};
class GeoCvor: public Cvor {
Mesto mst;
void pisi (ostream& d) { d << mst.ime() << '/' << vel (); }
public:
explicit GeoCvor (char oz, const Mesto& ms): Cvor (oz), mst (ms) {}
double vel () const { return mst.obim (); }
Tacka centar () const { return mst.centar (); }
};
class Grana {
Grana (const Grana&) {}
void operator= (const Grana&) {}
protected:
char ozn; const Cvor *poc, *kra;
public:
Grana (char oz, const Cvor* po, const Cvor* kr) {ozn = oz; poc = po, kra = kr; }
virtual ~Grana () {}
char oznaka () const { return ozn; }
virtual double duz () const =0;
friend ostream& operator<< (ostream& d, const Grana& g)
{ return d << g.ozn << '(' << g.poc->oznaka() << ',' << g.kra->oznaka() << ')'; }
};
class GeoGrana: public Grana {
public:
GeoGrana (char oz, const GeoCvor* po, const GeoCvor* kr): Grana (oz, po, kr) {}
double duz () const {
const GeoCvor* cv1 = static_cast<const GeoCvor*>(poc);
const GeoCvor* cv2 = static_cast<const GeoCvor*>(kra);
return cv1->centar().rastojanje (cv2->centar());
}
};
class GIndeks {
friend ostream& operator<< (ostream& d, const GIndeks&)
{ return d << "*** Nedozvoljeni indeks!"; }
};
class GPun {
friend ostream& operator<< (ostream& d, const GPun&)
{ return d << "*** Niz je pun!"; }
};
template <typename T>
class Niz {
T* niz; int kap, duz;
void kopiraj (const Niz& n);
public:
explicit Niz (int k=10) { niz = new T [kap = k]; duz = 0; }
Niz (const Niz& n) { kopiraj (n); }
~Niz () { delete [] niz; }
Niz& operator= (const Niz& n) {
if (this != &n) { delete [] niz; kopiraj (n); }
return *this;
}
int vel () const { return duz; }
Niz& operator+= (const T& t) {
if (duz == kap) throw GPun ();
niz[duz++] = t;
return *this;
}
T& operator[] (int i) {
if (i<0 || i>=duz) throw GIndeks ();
return niz[i];
}
const T& operator[] (int i) const {
if (i<0 || i>=duz) throw GIndeks ();
return niz[i];
}
Niz& isprazni () { duz = 0; }
};
template <typename T>
void Niz<T>::kopiraj (const Niz& n) {
niz = new T [kap = n.kap]; duz = n.duz;
for (int i=0; i<duz; i++) niz[i] = n.niz[i];
}
class GCvor {
friend ostream& operator<< (ostream& d, const GCvor&)
{ return d << "*** Neispravna oznaka cvora!"; }
};
class GGrana {
friend ostream& operator<< (ostream& d, const GGrana&)
{ return d << "*** Neispravna oznaka grane!"; }
};
class GeoKarta {
Niz<GeoCvor*> cvori;
Niz<GeoGrana*> grane;
GeoKarta (const GeoKarta&) {}
void operator= (const GeoKarta&) {}
public:
GeoKarta (int ncv, int ngr): cvori(ncv), grane(ngr) {}
~GeoKarta ();
GeoKarta& dodajCvor (GeoCvor& cv) { cvori += new GeoCvor (cv); return *this; }
GeoKarta& dodajGranu (GeoGrana* gr) { grane += gr; return *this; }
const GeoCvor* dohvatiCvor (char ozn) const;
const GeoGrana* dohvatiGranu (char ozn) const;
};
GeoKarta::~GeoKarta () {
for (int i=0; i<cvori.vel(); delete cvori[i++]);
for (int i=0; i<grane.vel(); delete grane[i++]);
}
const GeoCvor* GeoKarta::dohvatiCvor (char ozn) const {
for (int i=0; i<cvori.vel(); i++)
if (cvori[i]->oznaka() == ozn) return cvori[i];
throw GCvor ();
}
const GeoGrana* GeoKarta::dohvatiGranu (char ozn) const {
for (int i=0; i<grane.vel(); i++)
if (grane[i]->oznaka() == ozn) return grane[i];
throw GGrana ();
}
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
//
int main () { //
GeoKarta karta (2,1); //
Mesto bg ("Beograd", 3); //
bg.postavi(Tacka(1,1),0); //
bg.postavi(Tacka(2,1),1); //
bg.postavi(Tacka(2,2),2); //
karta.dodajCvor (GeoCvor('A', bg)); //
Mesto ni ("Nis", 3); //
ni.postavi(Tacka(-1,-1),0); //
ni.postavi(Tacka(-2,-1),1); //
ni.postavi(Tacka(-2,-2),2); //
karta.dodajCvor (GeoCvor('B', ni)); //
try { //
karta.dodajGranu (new GeoGrana('x', karta.dohvatiCvor('A'), //
karta.dohvatiCvor('B'))); //
cout << karta.dohvatiGranu('x')->duz() << endl; //
} catch (GCvor g) { cout << g << endl; } //
catch (GGrana g) { cout << g << endl; } //
return 0; //
} //
//
/////////////////// NIJE DEO RESENJA KOLOKVIJUMA ////////////////////
(⇒ почетак)
Copyright © 2010, Laslo Kraus
Последња ревизија: 30.8.2010.