OGP Reeks 1
Labo Object-geöriënteerd programmeren 2009-2010
Reeks 1
De eerste reeksen oefeningen zijn in C++. Later werken we met Java.
In de labo-les is er niet genoeg tijd om alle oefeningen af te werken. Doe dat thuis!
We controleren tijdens de les wat je thuis gedaan hebt; dan is er ook tijd voor bespreking of discussie. Je zult ook geregeld iets moeten afgeven.
Noteer de tijd die je thuis besteed hebt aan opzoekwerk, ontwerp en programmeren.
Neem zelf initiatief om dingen op te zoeken in cursussen, boeken of via het internet, zowel thuis als tijdens de les. Wissel inzichten uit met medestudenten.
Het is wel de bedoeling dat je naar de theorieles gaat en goed voorbereid naar de les komt.
Trek tijd uit om te experimenteren. De opdrachten zijn slechts een aanzet; wees creatief!
Aandacht voor stijl is belangrijk. Indenteren, hoofdletters, naamgeving etc. moeten bijdragen tot de leesbaarheid van de code.
Het is heel belangrijk om de code vaak te compileren (en dus ook te bewaren).
Besteed veel aandacht aan het testen van je code. Het is zelfs aan te raden om de testcode eerst te schrijven.
We gebruiken UML om klassediagrammen te tekenen. Probeer dit ook!
1. Naamgeving
Beschouw volgende code (bevat fouten):
/*
de klasse Persoon
*/
class Persoon {
string achternaam;
string voornaam;
int leeftijd; // in jaren
public:
Persoon(string voornaam_, string achternaam_, int leeftijd_ = 0) {
voornaam = voornaam_;
achternaam = achternaam_;
leeftijd = leeftijd_;
}
string get_voornaam() { return voornaam; }
string get_achternaam() { return achternaam; }
string get_naam();
int get_leeftijd() { return leeftijd; }
void set_leeftijd(int leeftijd_) { leeftijd = leeftijd_; }
}
string Persoon::get_naam() {
return voornaam + " " + naam;
}
void schrijf(Persoon p) {
cout << "voornaam: " << p.voornaam << endl
<< "achternaam: " << p.achternaam << endl
<< "leeftijd: " << p.leeftijd << endl;
}
int main() {
Persoon jan("Jan", "Janssen", 12)
cout << jan.get_naam() << endl;
Persoon personen[2];
personen[0] = jan;
personen[1].voornaam = "piet";
personen[1].achternaam = "pietersen";
personen[1].leeftijd = 15;
for (int i=0; i<2; i++)
schrijf(personen[i]);
return 0;
}
-
Verbeter de fouten.
- Duid aan:
a. commentaar b. type c. operator d.attribuut
e. veld (field) f. lid (member) g. lidfunctie h. methode
i. functie j. uitwendige (externe) functie k. inline methode
l. procedure m. argument n. parameter o. lokale variabele
p. globale variabele q. constante r. letterlijke constante (literal)
s. declaratie t. definitie u. interface v. implementatie
w. signatuur x. tabel (array) y. index z. constructor
A. destructor B. copy constructor C. default constructor
2. pointers en tabellen
Zoek de fouten en voorspel wat er uitgeschreven wordt:
const int N = 10;
int n;
cin >> n;
double tabel1[10];
double tabel2[N];
double tabel3[n];
double *tabel4 = new double[n];
double t[] = {1.1, 2.2, 3.3};
cout << t[3] << endl;
double *p = t;
cout << *p << endl;
cout << p[1] << endl;
p++;
cout << *p << endl;
t++;
cout << sizeof(double) << endl;
cout << sizeof(t) << endl;
cout << sizeof(p) << endl;
cout << sizeof(t)/sizeof(double) << endl;
3. Grote objecten doorgeven
Maak de code van oef.1 efficiënter (tip: de strings zijn "grote objecten")
Voeg waar gepast const toe
C++ in NetBeans
In het labo werken we met NetBeans in Linux: uitleg vind je
hier.
5. ArrayList
We maken een klasse ArrayList die zich gedraagt zoals de ArrayList in Java, te vergelijken met std::vector in C++.
Een ArrayList is een collectie/container die lijkt op een tabel, maar waaraan men elementen (achteraan) kan toevoegen. Achter de schermen bevindt zich een tabel met een bepaalde capaciteit, waarvan een deel (grootte) gebruikt wordt.
-
We pakken dit probleem stap voor stap aan. In eerste instantie maken we een ArrayList die reële getallen (type double) kan bevatten, met een vaste capaciteit.
Voorzie volgende methodes:
capacity(): geeft de capaciteit
size(): geeft de (gebruikte) grootte
add(x): voegt x toe indien mogelijk - exceptie indien overflow
get(i): geeft i-de element (vanaf nul geteld) - exceptie indien i ongeldig
set(i, x): geeft i-de element de waarde x - exceptie indien i ongeldig
clear(): wist alle elementen
is_empty(): true indien de lijst leeg is, anders false
schrijf(delimiter): schrijft alle elementen uit, gescheiden door de string delimiter, die default een spatie is.
Opm.
- Implementeer deze methodes één voor één, en test telkens uit.
- Gebruik waar aangewezen
const &
- Maak het mogelijk om de initiële capaciteit mee te geven via de constructor. Indien er geen capaciteit opgegeven wordt, neem dan een default waarde 10.
- Zorg nu voor onbeperkte toevoegmogelijkheid. Ga als volgt te werk: indien bij het toevoegen de volledige capaciteit benut is, alloceer dan een nieuwe tabel die dubbel zo groot is, kopieer de eerste tabel, voeg het nieuwe element toe en verwijder de oude tabel. (Op deze manier wordt het toevoegen gemiddeld een O(1) operatie)
- Breng declaratie en implementatie van de klass
ArrayList onder in een headerbestand "arraylist.h". Pas uiteraard het hoofdprogramma aan.
- Maak van
ArrayList een template klasse, die elementen van willekeurig type T kan bevatten. Zorg voor een efficiënte behandeling indien T "groot" is.
- Zorg er d.m.v. operator overloading voor dat je een
ArrayList kunt indexeren met vierkante haakjes (zowel "lezen" als "schrijven" van een element)
6. Extra: gelinkte lijst
Maak een klasse List met dezelfde interface als ArrayList, behalve capacity, maar geïmplementeerd d.m.v. een enkel-gelinkte lijst. Alle operaties behalve get(), set() en schrijf() moeten efficiënt zijn (0(1)).
|
|