HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring Kandidatnr: Eksamensdato: 26.mai 2005 Varighet: 0900-300 Fagnummer: Fagnavn: Klasse(r): LV95D Objektorientert programmering i C++ nettstudenter Studiepoeng: 2 Faglærer(e): Else Lervik, tlf. 73 55 95 50 / 99 32 04 9 Hjelpemidler: Oppgavesettet består av: Vedlegg består av: Lærebøker, alle håndskrevne og trykte hjelpemidler. 3 oppgaver og 6 sider (inkludert forside og vedlegg) 3 sider Merknad: Oppgaveteksten kan beholdes av studenter som sitter eksamenstiden ut. Lykke til!
Generell informasjon All programmering skal skje i C++. Det er tillatt å bruke klasser fra leksjoner, øvingsopplegg og lærebok. Ta i tilfelle med henvisninger til hvor klassen er å finne. Les gjennom hele oppgavesettet før du begynner å programmere. Pass på at du ikke gjør verken mer eller mindre enn det oppgavene spør etter. Men dersom du trenger flere funksjoner/konstruktører for å lage de funksjonene oppgavene spør etter, skal du også programmere disse. En fornuftig oppdeling i funksjoner ut over det oppgaven spør etter, kan gi plusspoeng ved bedømmelsen. Dersom du mener det mangler opplysninger, sett dine egne forutsetninger. Feilsjekking skal utføres, men feilene behandles kun på enkleste måte, dvs. at du kan la funksjonene returnere -, false eller 0, avhengig av returtypen. Innledning Sammen med en utgiver av lærebøker selger en høgskole nettfag. Kundene kan bestille fag for ulike semestre i samme ordre som de bestiller lærebøker. Bøkene sendes ut umiddelbart, mens faktura for fagene sendes i begynnelsen av det semesteret faget skal kjøres. Som en følge av dette vil én ordre kunne resultere i flere fakturaer, en for bøkene som bestilles og en for hvert semester kunden skal ta fag. Følgende modell er gitt: AlleOrdrer * Ordre * Faktura * Fakturalinje Bokfaktura Fagfaktura Oppgave vekt 5% Vi vil trenge en klasse som beskriver et semester. Et semester er identifisert ved del ("høst"/"vår") og årstall. Lag klassen Semester. Klassen skal ha del ("høst"/"vår") og årstall som datamedlemmer. Klassen skal ha finn-funksjoner for begge datamedlemmene, og den skal ha operatoren == som returnerer true dersom to semestre er like. For at to semestre skal være like må begge datamedlemmene være like. Eksakt likhet kreves, det vil si at du ikke trenger å tenke på at f.eks. "HØST" og "høst" er like dersom den første omformes til bare små bokstaver. Klassen skal ha en konstruktør som sjekker at inn-argumentene er korrekte. Eventuelle feil skal rapporteres til klienten. Kravene er som følger: del skal være lik "høst" eller "vår" (små bokstaver) og årstall skal være større eller lik 970 og mindre eller lik 2025. Også her kreves eksakthet, det vil si at f.eks. "HØST" skal rapporteres som feil. Konstruktøren skal kunne brukes på følgende måte: Semester sem("høst", 2005); Lag en bit av et klientprogram som prøver denne feilhåndteringen. 2
Oppgave 2 vekt 55% Du skal i denne oppgaven lage klassen Faktura med subklasser. For å spare skrivearbeid skal du kun oppgi datamedlemmene og implementere medlemsfunksjonene. Det vil si at du ikke trenger å sette opp alle funksjonsprototypene i klassedefinisjonene. Klassen Faktura har ordredato, fakturanummer og en tabell av fakturalinjer (se vedlegg ) som datamedlemmer. Tabellen skal ligge i det frie lageret. Oppgave a) Definer datamedlemmene. Bruk klassen Dato, se vedlegg 2. Lag medlemsfunksjoner i de tre Faktura-klassene slik at det er mulig å sende følgende meldinger til objektene: finn fakturanummeret finn summen på fakturaen, det vil si summen av alle fakturalinjene finn betalingsfristen. For bøker er den lik dagens dato pluss 4 dager. For fag gjelder at dersom dagens dato er tidligere enn 4 dager før semesterstart, så er betalingsfristen lik semesterstart. Ellers er betalingsfristen lik dagens dato pluss 4 dager. Semesterstart er 5.august for høstens fag og 5. januar for vårens fag. Oppgave b) Tips: Avhengig av hvordan du løser oppgaven, kan du trenge å omforme tall til tekst. Du kan da anta at det eksisterer en ikke-medlemsfunksjon som gjør dette. Funksjonen har følgende prototyp: string lagtekst(int tall); Lag konstruktører, eventuelle destruktører og operatorer slik at klientprogrammet i vedlegg 3 fungerer. Det er ikke viktig at utskriften av fakturainformasjon formatteres, men alle data må være med i riktig rekkefølge. Oppgave 3 vekt 30% Du skal i denne oppgaven lage deler av klassene AlleOrdrer og Ordre. Om du trenger flere funksjoner enn du allerede har laget i Faktura-klassene, skal du også lage dem. For å spare skrivearbeid skal du kun oppgi datamedlemmene og implementere medlemsfunksjonene. Det vil si at du ikke trenger å sette opp alle funksjonsprototypene i klassedefinisjonene. Et objekt av klassen Ordre har ordrenr, ordredato og en samling fakturaer knyttet til seg. Bruk det frie lageret eller en STL-vektor til å lagre fakturaene. Alle ordrene samler vi i et objekt av klassen AlleOrdrer. Her skal du bruke en STL-vektor. En klient skal kunne sende følgende meldinger til et objekt av klassen AlleOrdrer. Registrer en ny ordre. Som argument skal et ordreobjekt sendes inn. Funksjonen må kontrollere at ordrer med denne ordreid ikke eksisterer fra før. Utover dette kan du anta at ordre-objektet er feilfritt. Finn summen av alle ordrer. Finn alle fagfakturaer for et bestemt semester. Husk å definere datamedlemmene i klassene Ordre og AlleOrdrer. 3
Vedlegg Klassen Fakturalinje #ifndef FAKTURALINJE_DEFINERT #define FAKTURALINJE_DEFINERT class Fakturalinje { public: Fakturalinje() {} Fakturalinje(int startartikkel, double startpris, int startantall = ) : artikkel(startartikkel), pris(startpris), antall(startantall) {} int finnartikkel() const { return artikkel; } double finnpris() const { return pris; } int finnantall() const { return antall; } double finnbelop() const { return pris * antall; } private: int artikkel; double pris; int antall; }; #endif 4
Vedlegg 2 Klassen Dato kjent fra eksempler og løsningsforslag Du kan anta at alle medlemsfunksjonene er implementert. #ifndef DATO_DEFINERT #define DATO_DEFINERT #include <string> using namespace std; class Dato { public: Dato(int nydag, int nymnd, int nyttaar); Dato(const string &nydato); // Format: ddmmaaaa Dato(); // dagens dato bool erok() const { return ok; } // sjekker at formatet er ok // Funksjonene returnerer false dersom datoen er ugyldig bool settdato(int nydag, int nymnd, int nyttaar); bool settdato(const string &nydato); // Format: ddmmaaaa void settdato(); // dagens dato int finndag() const { return dag; } int finnmnd() const { return mnd; } int finnaar() const { return aar; } void finndato(int &dagen, int &mnden, int &aaret) const; string finndato() const; // Format: ddmmåååå long int antalldagertil(const Dato &denandre) const; Dato operator+(int atdager) const; Dato operator-(int antdager) const; long int operator-(const Dato &DenAndre) const;// ant. dg. mellom to datoer Dato &operator++(); // Legger til en dag Dato &operator--(); Dato &operator+=(int antdager); Dato &operator-=(int antdager); bool operator==(const Dato &denandre) const; bool operator!=(const Dato &denandre) const; bool operator>(const Dato &denandre) const; bool operator<(const Dato &denandre) const; bool operator>=(const Dato &denandre) const; bool operator<=(const Dato &denandre) const; private:... uten interesse her... }; #endif 5
Vedlegg 3 klientprogram oppgave 2 Program: #include <iostream> using namespace std; int main() { Dato idag; Fakturalinje linjer[2] = {Fakturalinje(60, 400, 3), Fakturalinje(602, 500)}; Bokfaktura bf(02, linjer, 2, idag); cout << bf << endl; } Semester sem("høst", 2005); // fra oppgave Fakturalinje linjer2[3] = {Fakturalinje(603, 4000), Fakturalinje(604, 4500), Fakturalinje(605, 5050)}; Fagfaktura ff(03, linjer2, 3, idag, sem); cout << ff << endl; double fakturasum = bf + ff; // summerer beløpene på fakturaene cout << "Summen av faktura bf og ff er " << fakturasum << endl << endl; Fakturalinje linjer3[] = {Fakturalinje(63, 4000)}; Fagfaktura ff2 = ff; Fagfaktura ff3(04, linjer3,, idag, sem); cout << ff3 << endl; ff3 = ff2; cout << ff3 << endl; return 0; Utskrift fra kjøring: Fakturanr 02, betalingsfrist: 5082005 60 400 3 602 500 Sum faktura: 700 Fakturanr 03, betalingsfrist: 5082005 603 4000 604 4500 605 5050 Sum faktura: 3550 Summen av faktura bf og ff er 5250 Fakturanr 04, betalingsfrist: 5082005 63 4000 Sum faktura: 4000 Fakturanr 03, betalingsfrist: 5082005 603 4000 604 4500 605 5050 Sum faktura: 3550 6