Gevorderd Programmeren Praktijk nota’s
Opleiding Bachelor of Science in Informatica, van de Faculteit Wetenschappen, Universiteit Antwerpen. Nota’s bij de cursus voor academiejaar 2008 - 2009.
J. Broeckhove Onderzoeksgroep Computationeel Modelleren en Programmeren
Inhoudsopgave
1 C++ werkomgevingen en voorbeeldprogramma’s 1.1 Inleiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Voorbeeldprogramma’s . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Gebruik van de voorbeeldcode . . . . . . . . . . . . . . . . . . . . . . .
2 2 3 3
2 Codeer conventies 2.1 Makefiles . . . . . . . . . . . . 2.2 Organisatie van bronbestanden 2.3 Algemeen . . . . . . . . . . . 2.4 Indentatie . . . . . . . . . . . 2.5 Commentaar . . . . . . . . . . 2.6 Naamgeving . . . . . . . . . . 2.7 Preprocessing . . . . . . . . .
4 4 4 5 5 6 6 9
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
HOOFDSTUK
1
C++ werkomgevingen en voorbeeldprogramma’s
1.1 Inleiding De C++ practica bestaan 10 sessies van elk drie uur, in een van de computerlabo’s. Je werkt er onder SuSe Linux op een desktop werkstation. Dat geeft je de beschikking over een UNIX omgeving, met diverse grafische editors en met de tools die je nodig hebt: compiler (GNU gcc), linker, bijbehorende runtime libraries, make en doxygen. De make is build tool en doxygen is een documentatie generator. We werken in de practica in een Unix/Linux omgeving: daar zijn deze tools allemaal beschikbaar. Wie thuis geen Linux kan of wil installeren (als aparte partitie of via virtualizatie) kan de Cygwin omgeving onder Windows gebruiken. Er bestaan natuurlijk andere platformen en in het bijzonder ook zogenaamde IDE’s (Integrated development Environment). Er zijn evenwel twee goede redenen om bij de eerste kennismaking met C++ niet voor de kiezen: • Het is voor een informaticus belangrijke inzicht te hebben in in het functioneren van build tools, compilers enzomeer en daarvoor moet je ze eens expliciet gebruiken. Bij IDE’s functioneren die achter de schermen en dan verwerf je dat inzicht niet. • Het leren gebruiken van een IDE vergt tijd en moeite, en in het begin moet de focus volledig op de C++ liggen. De opgaven voor de practica worden wekelijks via het Blackboard systeem kenbaar gemaakt. Een van de elementen die de brug tussen theorie en practica slaat zijn de voorbeeldprogramma’s die je ter beschikking gesteld krijgt.
1.2. VOORBEELDPROGRAMMA’S
3
1.2 Voorbeeldprogramma’s De voorbeeldprogramma’s vormen een belangrijk onderdeel van het studiemateriaal. Deze programma’s worden in de theorieles gebruikt om mechanismen van C++ te verduidelijken en voor de practica zijn het interessante startpunten. Gevolg gevend aan hetgeen in voorgaande sectie werd gezegd, wordt het project meeggeven zonder enige IDE zoals bijvoorbeeld MS Visual of Eclipse. Het installeren en gebruiken is vrij eenvoudig en wordt ook in de practica uiteengezet. Samengevat 1. je expandeerd het gecomprimeerde file om zo de directory met de democode op je systeem aan te brengen 2. je gaat naar de project directory en vindt daar subdirectories die elk verband houden met een deel van het project Het file Readme.txt geeft een summier ovezicht van de directorystructuur van het project. In de subdirectory unix vindt men essenti¨ele file in verband met het gebruik van make. Het Readme.txt file daar geeft een summiere uiteenzetting over de targets. Een woord van waarschuwing: de makefiles in dit project zijn van een hoge complexiteit omdat ze een aantal werkmogelijkheden (zoals automatische detectie van nieuwe sources) implementeren die het gebruik van de projectstructuur zeer makkelijk maken. Het is niet vereist dat je ze van begin af aan kan ontleden en verder gebruiken.
1.3 Gebruik van de voorbeeldcode Het is uiteraard de bedoeling dat je de voorbeeldprogramma’s bestudeerd. Maar meer nog is het de bedoeling dat je als materiaal beschouwd waarmee je kan experimeteren. Je doet dat door de code te wijzigen en uit te breiden en te analyseren of ze nog compileerbaar of uitvoerbaar is en wat de uitvoering als resultaat oplevert.Op dit gebied is “oefening baart kunst” weldegelijk van toepassing en zal ook je inzicht in C++ groeien.
HOOFDSTUK
2
Codeer conventies
2.1 Makefiles In elk project komt minstens 1 makefile voor die minimaal volgende rules bevat • rule om het project te compileren, te linken en de doxygen documentatie te genereren (via make of make all) • rule om de objectfiles te verwijderen (via make clean)
2.2 Organisatie van bronbestanden Elk C++ bronbestand bestaat uit de volgende onderdelen 1. voor een headerfile, de multiple definition guard die meervoudige definitie door het meermaals includeren van het file verhindert 2. een algemeen commentaarblok in javadoc stijl dat volgende elementen bevat • korte beschrijving • @author • @date • @version 3. een include blok 4. de globale use statements
2.3. ALGEMEEN
5
5. het body-gedeelte Plaats een witregel tussen elk van deze onderdelen.
2.3 Algemeen Gebruik altijd slechts ´e´en statement per regel! Dus niet: a++;b++;
maar wel a++; b++;
Let er ook op dat je bij het aanroepen van procedures en methoden steeds de ronde haakjes plaatst, ook al geef je geen parameters mee!
2.4 Indentatie Alle onderdelen van sectie 2.2 worden tegen de kantlijn geplaatst.
2.4.1 Haakjes Hoewel er nog meerdere stijlen bestaan voor wat betreft het plaatsen van haakjes, zullen wij ´e´en van onderstaande conventies volgen. 1 2 3 4 5 6 7 8
int somefunction ( i n t someargument ) { ... f o r ( i = 0; i < 100; i ++) { ... } ... }
Het openingshaakje staat op dezelfde lijn als zijn voorganger en het sluitingshaakje op een nieuwe regel. Een andere stijl gebruikt die conventie voor blokken in een functie- of klassedefinitie, maar zet het openingshaakje voor functie bodies en klassedefinities op een nieuwe regel: 1 2 3 4 5 6 7 8 9
int somefunction ( i n t someargument ) { ... f o r ( i = 0; i < 100; i ++) { ... } ... }
2.5. COMMENTAAR
6
2.4.2 Regels afbreken Zorg ervoor dat de regels in uw code niet te lang worden (zodanig dat je niet moet gaan scrollen om een regel te lezen). Dikwijls is dit echter onvermijdelijk. Breek in die situaties de regel af en indenteer hem een tabpositie meer dan de eerste regel. Neem bij het afbreken volgende regels in acht: • breek af na een komma • breek af voor een operator • verkies higher-level -afbreken boven lower-level (zoals bijvoorbeeld in lange expressies
2.5 Commentaar Op sommige plaatsen (zoals bij lange, ingewikkelde expressies) kan het nodig zijn een woordje commentaar toe te voegen. Aarzel niet dit dan ook te doen. Procedures, klassen en methods worden ook voorzien van een commentaarblok in javadoc stijl met volgende gegevens: • korte beschrijving • @param voor elke gebruikte parameter • @return • @exception indien er exceptions gethrowd worden
2.6 Naamgeving Goede naamgeving is zeer belangrijk en dus is het aangewezen zo weinig mogelijk afkortingen te gebruiken en namen zo logisch mogelijk te kiezen (dus zorg ervoor dat ze overeenstemmen met de realiteit!).
2.6.1 Namespaces Namespaces beginnen steeds met een hoofdletter. In geval van meerdere woorden worden deze onderscheiden door een hoofdletter. Bijvoorbeeld: 1 2 3
namespace MyNameSpace { ... }
2.6. NAAMGEVING
7
2.6.2 Types, Acroniemen Begin de naam van een een type en een acroniem steeds met een hoofdletter. In geval van meerdere woorden worden deze onderscheiden door een hoofdletter. Bijvoorbeeld: 1 2
typedef i n t MyTypeDef SWLString myString ( " Secret World Live ! " )
// //
Type Acroniem
2.6.3 Templateparameters Templateparameters moeten steeds beginnen met de letter A. In geval van meerdere woorden worden deze onderscheiden door een hoofdletter. Bijvoorbeeld: 1 2 3 4
template
c l a s s FunctorTrait { ... };
//
AType
is
het
template
argument
2.6.4 Enumeraties Enumeraties beginnen steeds met de letter E en in geval van meerdere woorden worden deze onderscheiden door een hoofdletter. Bijvoorbeeld: enum EFreezeLevels {kFrozen=1, kThawn, kNone}
2.6.5 Klassen • Een basisklasse representeert fundamentele functionele objecten en begint steeds met een hoofdletter. • Een virtuele basisklasse begint steeds met een V. • Een pure virtuele klasse of interface begint steeds met de letter I. • Een klasse die sommige, maar niet alle, functionaliteit van een virtuele basisklasse implementeerd, wordt een mixin class genoemd. Deze klassen beginnen met de letter M. • Exceptionklassen beginnen steeds met een hoofdletter en eindigen op het woord Exception. • Klassen die design patterns implementeren beginnen steeds met een hoofdletter en eindigen met de naam van het design pattern. Bijvoorbeeld 1 2 3 4
c l a s s BaseClass { ... };
//
Basisklasse
2.6. NAAMGEVING
5 6 7
8
c l a s s VBaseClass { ... };
//
Virtuele
c l a s s IUserInterface { ... };
//
Interface
c l a s s MPrintable { ... };
//
Mixin
c l a s s Sta ndardE xcepti on { ... };
//
Exceptionklasse
c l a s s IconFactory { ... };
//
Factory
basisklasse
8 9 10 11 12 13 14 15
class
16 17 18 19 20 21 22 23
pattern
2.6.6 Procedures, methodes Procedures en methodes beginnen steeds met een kleine letter. In geval van meerdere woorden worden deze onderscheiden door een hoofdletter. Getters en setters beginnen steeds met set. . . , get. . . of is. . . (bij Booleans). Bijvoorbeeld: 1
i n t entier ( double x ) { return (( i n t ) x );}
//
functie
// //
methode setter
// //
getter boolean
2 3 4 5 6 7 8
c l a s s Full { bool stop ( long i n t size ); void setMessage ( std :: string & msg ); std :: string & msg getMessage (); bool isMessageSet (); };
2.7. PREPROCESSING
9
2.6.7 Variabelen Variabelen en parameters beginnen steeds met een kleine letter. Bovendien geldt: • globale en static variabelen beginnen met de letter g. • constanten beginnen met de letter k. • data members beginnen met de letter f. • static data members beginnen met de letters fg. Bijvoorbeeld: 1
i n t gCount
//
globale
variabele
// //
lokale static
//
constante
// //
data member static data
2 3 4 5 6 7 8
void foo () { i n t counter s t a t i c i n t gCounter const i n t kMaxCount (100) ... }
variabele variabele variabele
9 10 11 12 13 14 15
c l a s s MyClass { private : std :: string fName s t a t i c Date fgDefaultDate ... };
member
2.7 Preprocessing 2.7.1 Multiple Inclusion Guard De multiple inclusion guard zorgt ervoor dat er geen meervoudige definities kunnen voorkomen door het meermaals includeren van eenzelfde headerfile. Gebruik steeds INC_BESTANDSNAAMINHOOFDLETTERS_EXTENSIE Bijvoorbeeld: 1 2 3 4
# ifndef INC_VIDEO_H # define INC_VIDEO_H ... # endif / / I N C _ V I D E O _ H
2.7.2 Conditionele compilatie Makro’s laten toe om te switchen tussen broncode varianten. Gebruik ze enkel wanneer ze echt nodig zijn. Gebruik steeds het prefix DEF. Bijvoorbeeld:
2.7. PREPROCESSING
1 2
# define DEF_ARCH X86 ...
3 4 5 6 7 8
# ifdef DEF_ARCH == 86 ... else ... # endif / / D E F _ A R C H
10