compilatie
C++ is een taal met compilatie. Dat brengt met zich mee dat vooraleer een programma kan uitgevoerd worden, het volledige programma zal moeten omgezet worden in 1'en en 0'en. Deze compilatie gebeurt door een compiler. C++ laat gescheiden compilatie toe. Dat betekent dat verschillende eenheden van het programma afzonderlijk van elkaar (en op een ander tijdstip), kunnen gecompileerd worden. Zo een afzonderlijke eenheid wordt een "translation unit" genoemd en bestaat typisch uit een .cpp-bestand (source file) en bijhorende .h-bestanden (header files).
Wanneer alle afzonderlijke eenheden gecompileerd zijn, worden ze met elkaar verbonden door de linker. Wanneer het linken voltooid is, dan zal er een executable gegenereerd worden. In Windows hebben deze executables meestal de .exe extentie, terwijl ze in Linux meestal extensieloos zijn.
een eerste C++-programma
Een C++-programma begint typisch bij de main() functie. Wanneer deze functie volledig uitgevoerd is, dan wordt het programma beindigd. Een eenvoudig C++ - programma zou er bijvoorbeeld als volgt kunnen uitzien
main.cpp
Code: Select all
#include <iostream>
int main() {
std::cout << "hallo wereld \n";
}
Een tweede punt dat valt te bemerken is dat van std:: . In C++ komen objecten en functies vaak in namespaces voor. Een namespace is een ruimte waarbinnen een reeks objecten en functies voorkomen met ondubbelzinnige namen. In een namespace wiskunde zouden bijvoorbeeld de functies double cos(double x), double sin(double x) en double tan(double x) kunnen voorkomen. De namespace std is een namespace waarin heel wat handige functies gedeclareerd en gedefinieerd zijn. Hierbij denk ik bijvoorbeeld aan lijsten, vectoren, algoritmes, ... . Wanneer je functies en objecten wil gebruiken die buiten je namespace gedeclareerd zijn, dan zal je deze moeten kwalificeren met de naam van de namespace gevolgd door de scope operator (::). In ons programma bevinden we ons in de default namespace. Daarom moeten we std::cout schrijven om het object cout uit de namespace std te gebruiken.
modules
In C++ zijn modules (of in de Java context ook wel packages genoemd) niet fysiek tastbaar. We zullen modulariteit daarom trachten te verkrijgen met namespaces. We zullen functies en objecten die met elkaar te maken hebben typisch declareren en definieren in eenzelfde namespace. Zo kan je voor een game als "space invaders" bijvoorbeeld een namespace si maken. Om een spaceship te declareren en te definieren in de namespace si, zullen we als volgt te werk gaan.
spaceShip.h
Code: Select all
namespace si {
class SpaceShip{
public:
void fire();
int getHp();
void setHp(int hp);
private:
int fHp; // number of hitpoints
int fBullets // number of bullets left
};
}
Code: Select all
#include "spaceShip.h"
namespace si {
void SpaceShip::fire() {
fBullets = fBullets - 1;
std::cout << "we schieten een kogel" << std::endl;
}
int SpaceShip::getHp() {
return fHp;
}
void SpaceShip::setHp(int hp) {
fHp = hp;
}
}
main.cpp
Code: Select all
#include "spaceShip.h"
int main() {
si::SpaceShip ship();
ship.setHp(100);
ship.fire();
}
types: declaratie en definitie
Om een variabele in C++ te gebruiken, zal men deze eerst moeten declareren. Hiermee wordt bedoelt dat je aan elke variabele zal moeten zeggen van welk type hij is. Voorbeelden van declaraties zijn
Code: Select all
int i; // i is een geheel getal
double j; // j is een decimaal getal
std::string s; // s is een string
Car c1; // c1 is een Car
Car* c2; // c2 is een pointer naar een Car
Code: Select all
int i = 5;
std::string zin = "hallo allemaal";
Car* c5 = new Car();
Car c6("ferrari",140);
Car c7;
Code: Select all
int getal;
getal = 5;
std::cout << "het getal is gelijk aan " << getal << std::endl;
In C++ wordt er veel gebruik gemaakt van pointers. Pointers heb je in C++ immers nodig om op run-time geheugen te alloceren. Hiervoor gebruiken we meestal de operator new van een object. Bijvoorbeeld: wanneer we op run-time geheugen willen vragen voor een nieuw Car-object, zullen we als volgt te werken gaan.
example1.cpp
Code: Select all
int main() {
// heel wat operaties
Car* c = new Car(); // we vragen dynamisch geheugen aan
// heel wat operaties
}
example2.cpp
Code: Select all
int main() {
// heel wat operaties
Car* c = new Car(); // we vragen dynamisch geheugen aan
// heel wat operaties
delete c;
// heel wat operaties
}
In C++ kan je variabelen aan een functie by value en by reference doorgeven. Wanneer je een variabele by value doorgeeft, dan zal er eerst een copy van die variabele gemaakt worden en deze zal dan worden doorgegeven. Als de variabele een object is, dan wordt de copy-constructor van dit object opgeroepen. Wanneer de functie wordt beindigd, dan is de waarde van de variabele onaangepast.
Wanneer je een variabele by reference doorgeeft, dan zal het geheugenadres van de variabele in kwestie doorgegeven worden. Wanneer de functie wordt beindigd, dan is de waarde van de variabele wel aangepast.
pass by value
Code: Select all
void rekenFunctie(int a, int b, int resultaat) {
resultaat = a + b;
}
int main() {
int getal1 = 5;
int getal2 = 10;
int getal3 = 0;
rekenFunctie(getal1,getal2,getal3);
std::cout << "getal 3 = " << getal3 << std::endl;
}
pass by reference
Code: Select all
void rekenFunctie(int a, int b, int& resultaat) {
resultaat = a + b;
}
int main() {
int getal1 = 5;
int getal2 = 10;
int getal3 = 0;
rekenFunctie(getal1,getal2,getal3);
std::cout << "getal 3 = " << getal3 << std::endl;
}
objecten
Wanneer we in C++ over objecten spreken, dan hebben we het vaak over een pointer naar een instantie van een klasse. Bijvoorbeeld een pointer naar een Car, een pointer naar een SpaceShip, een pointer naar een Entity, ... .
Concreet ziet een object er in C++ dat als volgt uit
Code: Select all
Car* c = new Car(); // een Car object
SpaceShip* spaceShip = new SpaceShip(); // een SpaceShip object
Entity* e = new Entity(); // een Entity object
Als we het niet hebben over een pointer naar een instantie van een klasse dan hebben we het over de instantie van de klasse zelf. Concreet ziet een object er in C++ dan als volgt uit.
Code: Select all
Car c;
SpaceShip spaceShip;
Entity e;