TL5302 Olio-ohjelmointi Koe 19.4.2005 Malliratkaisuja Tehtävä 1 Tässä sekä a)- että b)-kohdan toimiva ratkaisu: #include <iostream> using namespace std; int main() int taul[5]=1,2,3,4,5; int *p,&r=taul[0]; p=taul;//tai p=&taul[0]; int *q; q=&taul[4]; do cout << *p << " " << r << endl; p++; r++; while (p<=q); Myös seuraava toimii a)-kohdassa: q=p+4; do cout << *p++ << endl; while (p<=q); Tämä toimii myöskin: for (int i=0;i<5;i++)
cout << *(p+i) << endl; Joku viisas oli keksinyt b)-kohtaan näin originellin ratkaisun, joka myös toimii int (&r)[5]=taul; for (int i=0;i<5;i++) cout << r[i] << endl; Tehtävä 2 class sylinteri double korkeus,sade; sylinteri(); sylinteri(const double k,const double s); double lasketilavuus(); void tulosta(); void muutaarvot(); ; sylinteri::sylinteri() korkeus=0;sade=0; sylinteri::sylinteri(const double k,const double s) korkeus=k;sade=s; void sylinteri::muutaarvot() cout << "Uusi korkeus " << endl; cin >> korkeus; cout << "Uusi säde " << endl; cin >> sade; double sylinteri::lasketilavuus() return 3.141592*sade*sade*korkeus;
void sylinteri::tulosta() cout << "Korkeus on " << korkeus << " säde on " << sade << endl; int main() sylinteri x; sylinteri y(2,2); x.tulosta(); y.tulosta(); x.muutaarvot(); x.tulosta(); cout << "x:n tilavuus on " \ << x.lasketilavuus() << " ja y:n tilavuus on " \ << y.lasketilavuus() << \endl; Tämä tehtävä oli yleisesti ottaen osattu ylivoimaisesti parhaiten. Saman tyyppistä laatikko-tehtävää tosin tunnilla jauhettiin kyllästymiseen asti...
Tehtävä 3 a) Kohdasta sai 1 pisteen, jos osasi piirtää luokkahierarkian Muoto Sylinteri Ellipsoidi Särmiö Pallo Kuutio Toisen pisteen tienasi, jos osasi selittää tästä jotain lisäksi, esim. että Muoto on kantaluokka ja muut johdettuja luokkia. Lisäksi tässä olisi voinut esittää, mitä ominaisuuksia kaikilla muodoilla on yhteistä (tilavuus!) ja mitä pitää toteuttaa aliluokissa erikseen (tilavuuden laskenta). b) Tässä on tilavuudenlaskentaohjelma kokonaisuudessaan. Tietenkään 2 pisteeseen ei vaadittu näin perusteellista ratkaisua, mutta luokkien toteutuksen oli kuitenkin oltava pääpiirteissään oikein. #include <iostream> #define PII 3.141592 using namespace std; class muoto double a,b,c; //Muotojen "sivujen pituudet" double tilavuus; muoto() tilavuus=0; ; class ellipsoidi : public muoto ellipsoidi(const double &A,const double &B, const double &C) a=a; b=b; c=c;
ellipsoidi() a=b=c=0; ; double lasketilavuus() tilavuus=4/3*pii*a*b*c; return tilavuus; class pallo : public ellipsoidi pallo(const double &r) a=b=c=r; pallo() a=b=c=0; ; class sarmio : public muoto sarmio(const double &A,const double &B,const double &C) a=a; b=b; c=c; sarmio() a=b=c=0; double lasketilavuus() tilavuus=a*b*c; return tilavuus; ; class kuutio : public sarmio kuutio(const double &r) a=b=c=r; kuutio() a=b=c=0; ;
class sylinteri : public muoto double sade; sylinteri(const double &h, const double &r) a=b=c=h; sade=r; sylinteri() a=b=c=sade=0; double lasketilavuus() tilavuus=pii*sade*sade*a; return tilavuus; ; int main() pallo pall(3); ellipsoidi elli(3,3,3); sarmio sami(3,3,3); kuutio kuu(3); sylinteri syli(3,3); cout << "Pallin tilavuus on " << pall.lasketilavuus() << endl; cout << "Ellin tilavuus on " << elli.lasketilavuus() << endl; cout << "Samin tilavuus on " << sami.lasketilavuus() << endl; cout << "Kuun tilavuus on " << kuu.lasketilavuus() << endl; cout << "Sylin tilavuus on " << syli.lasketilavuus() << endl; Muutama kommentti. Muuttujat a, b ja c periytyvät kaikille aliluokille. Ne sisältävät eri muotojen dimensiot. Kunkin aliluokan muodostimet alustavat ne juuri sillä aliluokalle järkeviin arvoihin, esimerkiksi kuutiolle ja pallolle a, b ja c ovat samat. Arvo saadaan parametrillisen muodostimen välityksellä kuutio-olion luonnin yhteydessä. Tilavuuden laskenta on kirjoitettu vain Muodosta johdettuihin aliluokkiin sylinteri, ellipsoidi ja särmiö. Pallolle ja kuutiolle ei tarvitse kirjoittaa omaa tilavuuden laskentaa; ne perivät laskennan kantaluokaltaan.
Tehtävä 4 Tähän tehtävään kokeen mukana jaetussa koodissa oli hyvin paljon valmista apua, jos sitä olisi osannut hyödyntää. Tässä tarvittavat lisäykset luokan määrittelyyn on merkitty lihavoituna. Yhteenlaskulle oli jo olemassa ylikuormaus valmiiksi. Vähennyslasku on täysi sama, paitsi parista paikkaa olisi pitänyt plus vaihtaa miinukseksi! Kompleksilukujen kertolaskua ei osannut tehdä oikein kukaan, mutta onneksi tämä ei ole matikan kurssi Pisteen sai, jos koodi oli muuten oikein. Vastaavasti koodista löytyy jo valmis esimerkki yhtäsuuruusoperaattorin ylikuormaukselle. Pienempi- ja suurempikuin vertailut menevät paljolti samalla lailla, tosin tässä piti osata käyttää hyödyksi tietoa siitä, miten kompleksilukujen itseisarvo lasketaan. class complex double re,im; complex operator+(complex &); complex operator-(complex &); complex operator *(complex &); bool operator==(complex &); bool operator > (complex &); bool operator < (complex &); friend ostream &operator<<(ostream &,const complex &); complex(); complex(const double &,const double &); ; Tässä operaattoreiden toteutukset: complex complex::operator -(complex &x) complex tulos; tulos.re=this->re - x.re; tulos.im=this->im - x.im; return tulos; complex complex::operator *(complex &x) complex tulos; double a,b,c,d; //(a+jb)(c+jd)=(ac-bd)+j(ad+bc) a=this->re; b=this->im; c=x.re; d=x.im;
tulos.re=a*c-b*d; tulos.im=a*d+b*c; return tulos; bool complex::operator > (complex &p) double a=sqrt(this->re*this->re + this->im*this->im); double b=sqrt(p.re*p.re + p.im*p.im); if (a>b) return 1; else bool complex::operator < (complex &p) double a=sqrt(this->re*this->re + this->im*this->im); double b=sqrt(p.re*p.re + p.im*p.im); if (a<b) return 1; else Ja lopuksi vielä pääohjelma, jolla näitä operaattoreita voi testata: int main() complex x(1,1),y(2,2),z,t; z=x-y; t=x*y; if (x>z) cout << "x on suurempi kuin z " << endl; else cout << "z on suurempi kuin x " << endl; if (t<z) cout << "t on pienempi kuin z " << endl; else cout << "z on pienempi kuin t " << endl;