Objektorienterad programmering: Lösningar till tentamen 2006-12-20

Det här är förslag på lösningar. Det kan finnas andra lösningar som också är korrekta, och det kan hända att en del av lösningarna är mer omfattande än vad som krävs för full poäng på uppgiften. En del av lösningarna är kanske inte fullständiga, utan hänvisar bara till var man kan läsa svaret.

Uppgift 1 (2 p)

Skriv klassdefinitionen för klassen Person.
class Person {
private:
    string namn;
    int alder;
    double vikt;
public:
    Person(const string& namn, int alder, double vikt);
    const string& get_namn() const;
    int get_alder() const;
    double get_vikt() const;
};
Kommentar: Här och i fortsättningen har jag använt const mer än vad som egentligen krävs i den här kursen. const-deklarationer underlättar för kompilatorn att hitta fel, i och med att den kan upptäcka om programmeraren av misstag gör ändringar i data som inte skulle ändras, eller om programmeraren trodde att något skulle hålla sig oförändrat som kanske inte gör det.

Kommentar: Om man tar bort const bör medlemsfunktionen get_namn inte returnera en string&, utan en string:

    string get_namn();

Uppgift 2 (2 p)

Implementera konstruktorn och de övriga medlemsfunktionerna i Person.
Person::Person(const string& namn, int alder, double vikt) {
    this->namn = namn;
    this->alder = alder;
    this->vikt = vikt;
}

const string& Person::get_namn() const { return namn; }

int Person::get_alder() const { return alder; }

double Person::get_vikt() const { return vikt; }

Uppgift 3 (4 p)

Implementera medlemsfunktionerna skriv och las.
void Person::skriv() const {
    cout << "Namn: " << namn << endl;
    cout << "Ålder: " << alder << endl;
    cout << "Vikt: " << vikt << endl;
}

void Person::las() {
    cout << "Namn: ";
    getline(cin, namn);
    cout << "Ålder: ";
    cin >> alder;
    cout << "Vikt: ";
    cin >> vikt;

    while (cin.get() != '\n')
        ;
}

Uppgift 4 (2 p)

Implementera utskriftsoperatorn.
ostream& operator<< (ostream& o, const Person& person) {
    o << "Namn: " << person.namn << endl;
    o << "Ålder: " << person.alder << endl;
    o << "Vikt: " << person.vikt << endl;
    return o;
}

Uppgift 5 (4 p)

Skriv en main-funktion som testar klassen Person.
int main() {
    Person p("Olle", 27, 110.0);
    if (p.get_namn() == "Olle" && p.get_alder() == 27 && p.get_vikt() == 110.0)
        cout << "Rätt!" << endl;
    else
        cout << "Fel!" << endl;
    p.las();
    p.skriv();
    cout << p;

    return 0;
}

Uppgift 6 (3 p)

Skriv ett C++-program som läser in personer från standardinmatningen, och sparar dem på en fil.
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

#include "Person.h"

int main() {
    cout << "Skriv personer. Avsluta med en person med en tom sträng som namn." << endl;
    ofstream tsut("personer.txt");
    Person p("Ingen", -1, -1.0);
    p.las();
    while (p.get_namn() != "") {
        tsut << p.get_namn() << endl;
        tsut << p.get_alder() << endl;
        tsut << p.get_vikt() << endl;
        p.las();
    }

    return 0;
}
I den här lösningen lagras personerna på en textfil, och inmatningen avslutas genom att användaren matar in en person med en tom sträng som namn, alltså bara trycker RETUR som svar på frågan om namn.

Uppgift 7 (3 p)

Skriv ett C++-program som läser filen med personer från uppgiften ovan, och talar om den sammanlagda vikten av alla personer som väger mer än 100 kilo.
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

int main() {
    ifstream tsin("personer.txt");
    string namn;
    int alder;
    double vikt;
    double viktsumman = 0;

    getline(tsin, namn);

    while (tsin) {

        tsin >> alder;
        tsin >> vikt;
        while (tsin && tsin.get() != '\n')
            ;

        if (vikt > 100)
            viktsumman += vikt;

        getline(tsin, namn);
    }

    cout << "Viktsumman = " << viktsumman << endl;

    return 0;
}

Uppgift 8 (2 p)

Skriv klassdefinitionen för klassen LankadPerson.
class LankadPerson : public Person {
private:
    LankadPerson* next;
public:
    LankadPerson(const string& namn, int alder, double vikt, LankadPerson* next);
    LankadPerson* get_next();
};

Uppgift 9 (2 p)

Implementera konstruktorn för klassen LankadPerson.
LankadPerson::LankadPerson(const string& namn, int alder, double vikt, LankadPerson* next)
    : Person(namn, alder, vikt), next(next) { }

Uppgift 10 (3 p)

Skriv klassdefinitionerna för klasserna Dagisbarn och Dagispersonal, som båda ärver från LankadPerson.
class Dagisbarn : public LankadPerson {
public:
    Dagisbarn(const string& namn, int alder, double vikt, LankadPerson* next);
};

class Dagispersonal : public LankadPerson {
private:
    int max_antal_barn;
public:
    Dagispersonal(const string& namn, int alder, double vikt, LankadPerson* next, int max_antal_barn);
    int get_max_antal_barn();
};

Uppgift 11 (2 p)

Skriv klassdefinitionen för klassen Dagis.
class Dagis {
private:
    Dagisbarn* forsta_barnet;
    Dagispersonal* forsta_personalen;
public:
    Dagis();
    void nytt_barn(const string& namn, int alder, double vikt);
    void ny_personal(const string& namn, int alder, double vikt, int max_antal_barn);
    void skriv_statistik() const;
    ~Dagis();
};

Uppgift 12 (2 p)

Implementera funktionen ny_personal.
void Dagis::ny_personal(const string& namn, int alder, double vikt, int max_antal_barn) {
    Dagispersonal* pp = new Dagispersonal(namn, alder, vikt, forsta_personalen, max_antal_barn);
    forsta_personalen = pp;
}

Uppgift 13 (5 p)

Implementera funktionen skriv_statistik.
void Dagis::skriv_statistik() const {
    double viktsumman = 0;
    int antal_barn = 0;
    int maxsumman = 0;
    LankadPerson* pp;
    pp = forsta_barnet;
    while (pp != NULL) {
        viktsumman += pp->get_vikt();
        ++antal_barn;
        pp = pp->get_next();
    }
    pp = forsta_personalen;
    while (pp != NULL) {
        viktsumman += pp->get_vikt();
        maxsumman += ((Dagispersonal*)pp)->get_max_antal_barn();
        pp = pp->get_next();
    }

    cout << "Viktsumman = " << viktsumman << endl;
    cout << "Antal barn = " << antal_barn << endl;
    cout << "Maxsumman = " << maxsumman << endl;

    if (antal_barn > maxsumman)
        cout << "Varning! För många barn. Personalen räcker inte." << endl;
    else
        cout << "Ok. Personalen räcker." << endl;
}

Uppgift 14 (4 p)

Skriv en main-funktion som testar klassen Dagis.
int main() {
    Dagis d;
    d.ny_personal("Gun", 50, 70, 15);
    d.ny_personal("Aneta", 45, 70, 10);
    d.ny_personal("Arnold", 55, 90, 26);

    srand(time(NULL));

    for (int i = 0; i < 100; ++i)
        d.nytt_barn("Olle", rand() % 6 + 1, rand() % 70 + 40.0);

    d.skriv_statistik();

    return 0;
}


Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se) 30 december 2006