Sie sind auf Seite 1von 7

1 Bibliotheken (#includes)

<fstream>: Fileinput/-Output, (ofstream, ifstream, fstream)


<iostream>: cin, cout, cerr
Flags siehe Folie 58/59
<iomanip>: Manipulatoren
<cstring>: strlen(); strcpy(ziel, quelle);

<vector>: Dynamischer Array


<string>: String Datentyp
<algorithm>: z.B. sort (für sort muss operator< implementiert sein!)

<new>: Für new_handler (siehe unten)


<cassert>: Zusicherungen zur Entwicklungszeit (Design by contract)
2 Common Code
2.1 Klassendeklaration
#ifndef BETRAG_H
#define BETRAG_H

#include <iostream>
using namespace std;

class Betrag {
public:
Betrag(int e, int c):euro(e),cent(c) {};
int get_euro() const { return euro; }
int get_cent() const { return cent; }
private:
int euro;
int cent;
}

2.2 Verwendung von Referenzparametern


void kuerzen(long & i, long & k) {
long g = ggt(i,k);
i = i/g;
k = k/g;
}

2.3 Copy-Constructor
Mystring::Mystring(const Mystring& s) {
derstring = new char[strlen(s.derstring)+1];
strcpy(derstring, s.derstring);
}

2.4 Operatoren
// Pseudooperator
Betrag& Betrag::addiere(const Betrag& be) {
euro += be.euro + (cent + be.cent)/100;
cent = (cent + be.cent) % 100;
return *this;
}
//oder: Betrag& Betrag::operator+=(const Betrag & be) {
Betrag& Betrag::operator+(const Betrag& be) {
//siehe oben
}

// operator[], Referenzrückgabe, da LValue (== Zuweisung)


char& Mystring::operator[](int i) { return derstring[i]; }
// operator= (Zuweisungsoperator)
Mystring& Mystring::operator=(const Mystring& s) {
if(this != &s) {
delete[] derstring; // Achtung!!!
laenge = s.laenge;
derstring = new char[laenge];
strcpy(derstring, s.derstring);
}
return * this;
}

// friends (oder operator<<)


class Mystring {
friend ostream& operator<<(ostream& cout, const Mystring& s);
}

ostream& operator<<(ostream& cout, const Mystring& s) {


cout << s.derstring;
return cout;
}

// Typumwandlungskonstruktor
class Complex {
public:
Complex(double re): re(re), im(0) {}
friend Complex operator+(const Complex& r,
const Complex& z);
private:
double re, im;
}

Complex operator+(const Complex& r, const Complex& z) {


return Complex(r.re + z.re, r.im + z.im);
}

2.5 Templates
template<class T>
void swap(int& a, int& b) { void swap(T& a, T& b) {
int c = a; T c = a;
a = b; a = b;
b = c; b = c;
} }

template<class T>
class Array {
public:
Array(int l):laenge(l) { inhalt = new T[l]; }
~Array();
bool operator==(Array<T>& a);
private:
int laenge;
T* inhalt;
}
template<class T>
Array<T>::~Array(){delete[] inhalt);}

template<class T>
bool Array<T>::operator==(Array<T>& a) {
if(laenge != a.laenge)
return false;

for(int i = 0; i < laenge; i++)


if(inhalt[i] != a.inhalt[i])
return false;

return true;
}

// Templates mit mehrern Parametern


template<class T, int l>
class Sarray {
public:
private:
T daten[l];
}

int main() {
SArray<double, 100> sa;
Array<double> da(100);
}

2.6 Forwarddeklaration
class Fahrer; class Kfz;

class Kfz { class Fahrer {


: :
Fahrer* fahrer; Kfz* kfz;
: :
} }

2.7 Vererbung
class Kfz {…};
class Pkw:public Kfz {…};
class Dienstwagen:public Pkw:public Inventar {…};

// Abstrakte Basisklasse
class GraphObj {
virtual void zeichne() = 0;
}

2.8 Exceptions
try { double& operator[](int i) throw(int)
… // Execute {
} … // Do something
catch(int index) { throw i;
… // Errorhandling }
}
2.9 new_handler
#include <new>
void my_newhandler() {
cout << „Fehler bei new“ << endl << exit(-1);
}

int main() {
set_newhandler(my_newhandler);
int groesse;
cin >> groesse;
int * a = new int[groesse];
}

// Auslösen z.B. durch


for(int i = 0; i < 100000000; i++) {
int * b = new int[1000];
}
// in main

2.10 Assertions
#include <cassert>

double sub(int p, int q) {


std::assert(p != 0 && q != 0);
return static_cast<double>(p)/q;
}

int main() {
int p = 5; int q = 0;
double c = sub(p,q);
std::assert(c != 0);
}

2.11 Dateien einlesen


Int main() {
ifstream ein(„eingabe.dat“);
long i;
while(!ein.eof()) {
ein >> i;
if(ein.fail()) break;
cout << i << ‚ ‚;
}
}
#include <string>
#include <iostream>
#include <fstream>
using namespace std;

int main() {
string dateiname = „“;
cin >> dateiname;

ifstream rein(dateiname.c_str());

if(rein.rdstate() != 0) { //alt: if(rein.fail()) {…}


cout << „Nochmal:“;
cin >> name;
rein.clear();
rein.open(name.c_str());
if(rein.fail()) {
cout << „Fehler beim öffnen“ << endl;
return 1; //alt: exit(0);
}
}

in tanz;
rein >> anz;
double* feld = new double[anz];
rein >> feld[0];
double max = feld[0];

for(int i=1; i < anz; i++) {


rein >> feld[i];
if(max < feld[i])
max = feld[i];
}
cout << „Maximum: „ << max;
delete[] feld;
}
3 Smileys
1. Nur sehr kurze Funktionsdefinitionen innerhalb der Klassendeklaration
aufschreiben.
Wenn dann maximal 1 Zeile Quellcode (getter und setter)
Denn: Methoden in der Deklaration werden i.d.R. als Inline Funktionen
übersetzt, d.h. kein Funktionsaufruf, sondern Kopie des Inhalts an die
aufrufende Stelle im Programmcode Î längerer Code aber schnellere
Ausführung
2. Initialisierung wenn möglich mit Initialisierungslisten durchführen
Denn: denn ohne Initialisierungsliste werden bei der Erzeugung eines
Objektes zuerst die Variablen mit Zufallswerten initialisiert und anschließend
mit den aktuellen Werten überschrieben Î schneller Ausführung
3. Methoden, die Klassenelemente nicht verändern, immer als „const“
deklarieren
4. Nach Möglichkeit immer Referenzparameter in Funktionen übergeben
Denn: Objekte sind meist groß, Referenzparameter sind klein (Zeiger) dadurch
müssen Parameter nicht vollständig kopiert werden
5. Sollen Referenzparameter in der Funktion nicht verändert werden, dann
sollten diese als konstante Referenzen markiert werden
6. Forwarddeklaration von Klassen: Zwei Objekte können sich gegenseitig
kennen, und sich auch gegenseitig benutzen, sie können sich aber nicht
gegenseitig besitzen!
7. Operatoren nur so überladen, wie es dem üblichen Gebrauch mit
Standarddatentypen entspricht
8. Alle Methoden, die evtl. einmal abgeleitete werden könnten virtuell
Kennzeichnen (virtual), auch bei Destruktor, da sonst der
Basisklassendestruktor aufgerufen wird!
9. Die Angabe der geworfenen Ausnahmen in der Funktionsdefinition ist
guter Stil (void x( ) throw(excobj) { })

4 Casts
const_cast<char*>(char* const): Entfernt const von einem Datentyp
static_cast<char>(long): Gleitkommaumwandlung
reinterpret_cast: Gefährlicher Cast, da alles Konvertiert wird
(teilweise plattformabhängig, Zeigercasts)
dynamic_cast: Klassenvererbung

Das könnte Ihnen auch gefallen