Einführung in C++ - math.uni-heidelberg.de · Ubersicht¨ Comp.-A. Grundl. Sprache Kodierung...
Transcript of Einführung in C++ - math.uni-heidelberg.de · Ubersicht¨ Comp.-A. Grundl. Sprache Kodierung...
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Einfuhrung in C++
Jan Lellmann, Jorg Hendrik Kappes
January 8, 2008
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
1 Grundlagen ComputerarchitekturAbstrakter Aufbau eines Rechners nach von NeumannVom Maschinencode zur ProgrammierspracheCompiler vs. Interpreter
2 Grundlagen C++Unterschiede zu MathematicaLiteraturVom Code zum Programm
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
3 SprachelementeTypenOperatorenTypumwandlungenFelderZeigerVerschiedenesSchleifenKontrollstrukturenFunktionenSichtbarkeit, Gultigkeit und LebensdauerHeader
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
4 KodierungZahlensystemeFestkommazahlen
Betrag und VorzeichenEiner-KomplementZweier-Komplement
GleitkommadarstellungKodierung von Zeichen
ASCIIUnicode
5 Stack und HeapStackHeap
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
6 ObjektorientierungAllgemeinesMethodenKapselungGetter/SetterUberladen von OperatorenVererbungLaufzeitpolymorphieAbstrakte Klassen
7 Linken
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Abstrakter Aufbau eines Rechnersnach von Neumann
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Von Neumann Architektur
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Von Neumann Architektur
Rechenwerk
Fuhrt Rechenoperationen durch
Steuerwerk
Steuert die Befehlsabfolge
Ein-/Ausgabewerk
I/O-Schnittstelle fur z.B. Tastatur,Monitor, Maus ...
Speicherwerk
Speichert Daten und Programmeund stellt sie bereit
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Von Neumann Architektur - Speicher
Speicher
Speichert Daten und Programmcode gemeinsam
Besteht aus mehreren aufsteigend nummerierenSpeichereinheiten
Diese Nummern werden Adressen genannt
Sie konnen sich Speicher als eine Menge durchnummerierteKarteikartchen samt Verwaltung vorstellen.
ACHTUNG: Dies ist eine abstrakte Darstellung desSpeichers, die uns aber furs Erste reichen wird
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Vom Maschinencode zurProgrammiersprache
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Maschinensprache
Definition
Unter Maschinensprache versteht man ein System vonInstruktionen und Daten, die der Prozessor eines Computers direktausfuhren kann.
Beispiel
B4 09 8D 16 0D 01 CD 21 B8 00 4C CD 21 48 65 6C
6C 6F 2F 2C 20 77 6F 72 6C 64 21 24
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Assemblersprache
Definition
Eine fur den Menschen lesbare Form der Maschinensprache. JedeComputerarchitektur hat ihre eigene Assemblersprache.
Beispiel
,NASM Intel 8086 Assembler (DOS)
org 100h
start: MOV AH ,09h
LEA DX ,[msg]
INT 21h
MOV AX ,4C00h
INT 21h
msg: DB ’Hello , world!$’
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Hochsprachen
Definition
Fur den Menschen gut verstandliche und abstrakte Abfassung einesComputerprogramms. Das Ubersetzen in Maschinensprache ist inder Regel nicht mehr trivial.
Beispiel
// ISO C++
#include <iostream >
int main (){
std::cout << "Hello , world !" << std::endl;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Weiteres Beispiel
int n = 5;
004114 BE C7 45 F8 05 00 00 00 mov dword ptr [n],5
int f = 1;
004114 C5 C7 45 EC 01 00 00 00 mov dword ptr [f],1
for (int i = 2; i < n; ++i) {
004114 CC C7 45 E0 02 00 00 00 mov dword ptr [i],2
004114 D3 EB 09 jmp main+3Eh (4114 DEh)
004114 D5 8B 45 E0 mov eax ,dword ptr [i]
004114 D8 83 C0 01 add eax ,1
004114 DB 89 45 E0 mov dword ptr [i],eax
004114 DE 8B 45 E0 mov eax ,dword ptr [i]
004114 E1 3B 45 F8 cmp eax ,dword ptr [n]
004114 E4 7D 0C jge main +52h (4114 F2h)
f *= i;
004114 E6 8B 45 EC mov eax ,dword ptr [f]
004114 E9 0F AF 45 E0 imul eax ,dword ptr [i]
004114 ED 89 45 EC mov dword ptr [f],eax
}
004114 F0 EB E3 jmp main +35h (4114 D5h)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Compiler vs. Interpreter
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Compiler
Definition
Ein Compiler ist ein Computerprogramm, das einen Quelltext in einsemantisch aquivalentes Zielprogramm ubersetzt. Ublicherweisehandelt es sich dabei um die Ubersetzung eines in einerProgrammiersprache geschriebenen Quelltextes in Maschinencode.
Vor- & Nachteile
+ Erzeugt sehr schnellen und optimierten Code
+ Nicht zeitkritisch
− Erzeugter Code i.d.R plattformabhangig
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAufbau Maschinencode Compiler
Interpreter
Definition
Ein Interpreter ist ein Programm, das einen Quellcode imGegensatz zu einem Compiler nicht in eine auf dem System direktausfuhrbare Datei umwandelt, sondern den Quellcode einliest,analysiert und ausfuhrt. Die Analyse des Quellcodes erfolgt alsozur Laufzeit des Programms.
Vor- & Nachteile
+ Compilieren entfallt (plattformunabhangiger)
+ “Interaktiver”
− Langsamer - da schlecht optimierbar
− Nicht fur jede Programmiersprache geeignet
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Grundlagen C++
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
C und C++
1979 aus C weiterentwickelt, erst 1998 standardisiert:
Klassen/ObjekteKonstantenReferenzenboolesche TypenVereinfachungen (Kommentare, Speicherverwaltung,Inkrement-Operator ++)inzwischen: Templates, Ausnahmen, . . .
Die ersten C++ – Compiler waren Frontends, d.h. erzeugtenC-Code, der dann von einem C-Compiler ubersetzt wurde.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Vergleich Mathematica und C++
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Entwicklungszyklus
Mathematica
Quelltext wirdinterpretiert
Editor und Interpretersind integriert
Code lasst sich sofortausfuhren
Werte lassen sichinteraktiv manipulieren
⇒ Testen verschiedenerVarianten einfach und schnell
C++
Quelltext wird compiliert,d.h. in Maschinenspracheubersetzt und dabeioptimiert
Nach dem Compilierenkeine Anderungen mehrmoglich
Editor und Compiler vomKonzept her getrennt
⇒ Langerer Zyklus, aber keineProbleme mit unerwartetemSystemzustand
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Grundgedanke
Mathematica
Auf der untersten Ebenestehen Ausdrucke undErsetzungsregeln.
Der momentane Zustandwird durch die aktivenErsetzungsregeln definiert.
Ein Programm ist eingultiger Ausdruck.
C++
Auf der untersten Ebenestehen Anweisungen undSpeicher.
Der momentane Zustandwird durch den Inhalt vonSpeicherzellen definiert.
Ein Programm ist eineFolge von Anweisungen,die den Speichermanipulieren.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Einsatzbereich
Mathematica
schnellePrototypenentwicklung
symbolisches Rechnen
Visualisierung
Sehr viele mathematischeVerfahren bereitsintegriert
C++
große Softwareprojekte
Echtzeitanwendungen
Hardwarezugriff
Optimierung undBeschleunigung
auf fast allen Plattformenverfugbar
große Anzahl anBibliotheken verfugbar
Fazit
Je nach Anwendung das passende Werkzeug auswahlen!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Literatur
Skript Fachhochschule Gießen-Friedberg(http://velociraptor.mni.fh-giessen.de/Programmierung/progI.pdf)
http://www.cplusplus.com/
Bjarne Stroustrup - Die C++ Programmiersprache
Stanley B. Lippman - C++ Primer
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Vom Code zum Programm in C++
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Hallo Hoersaal in C++
Wie schreibt man ein Programm?
1 Offnen Sie einen Editor (z.B. emacs)
2 Schreiben Sie ihr Programm (z.B. das unten)
3 Speichern Sie es als programm.cpp ab
C++ Code
// ISO C++
#include <iostream >
int main (){
std::cout << "Hallo Hoersaal" << std::endl;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Kompilieren eines Programmes
Wie kompiliert man ein Programm?
1 Stellen Sie sicher, dass ein C++ Compiler auf ihrem Systeminstalliert ist (Blatt 1).
2 Offnen Sie eine Kommandozeile, wechseln sie in dasVerzeichnis ihrer Quellcode-Datei.
3 Kompilieren Sie ihr Programm z.B. mit dem Befehlg++ -W -Wall -pedantic -std=c++98 programm.cpp -o programm
Alternativen
Es gibt auch Entwicklungsumgebungen, die einen Editorbereitstellen und es ermoglichen, direkt mit einerTastenkombination Ihr Programm zu kompilieren.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenC++ vs. MM Literatur Code→Programm
Ausfuhren eines Programmes
Ausfuhren in der Kommandozeile
Tippen Sie einfach den Namen der erzeugten Datei ein, z.B../programm.
Ausfuhren in einer Entwicklungsumgebung
In der Regel gibt es hierfur eine Tastenkombination oder denMenupunkt Ausfuhren oder Run.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sprachelemente
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Typen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Typisierung
Variablenname steht fur eine Adresse im Speicher.
Jede Variable hat einen Typ. Mischen von Typen fuhrtpotentiell zu Inkonsistenzen oder Datenmull.
Mathematica
s = "Hallo , Hoersaal"
(* Head[s] === String *)
s = 2.0
(* Head[s] === Real *)
Kopf gibt Typ an undkann sich zur Laufzeitandern.
Datenstrukturen (List)haufig unabhangig vomDatentyp (bequemer).
C++
string s;
s = "Hallo , Hoersaal ";
s = 2.0; // Fehler
Typ steht zum Zeitpunktdes Kompilierens fest.
Datenstrukturen in derRegel an Datentypgebunden (schneller).
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Darstellung
Der Typ einer Variablen legt fest, wie der Inhalt des zugeordnetenSpeichers interpretiert werden soll.Beispiel fur 2 Bit:
00 → 0, 01 → 1, 10 → 2, 11 → 3
00 → 0, 10 → 1, 01 → 2, 11 → 3
00 → −1.5, 01 → 14, 01 → 0, 11 →∞00 → rot, 01 → gelb, 10 → grun, 11 → blau
. . .
Zu einem Datentyp gehoren
eine Menge von Werten,
eine Menge von Literalen zur Bezeichnung von Werten und
eine Menge von Operationen auf den Werten.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Elementare Datentypen
Elementare Datentypen sind fest im Compiler eingebaut.
Wertebereiche und Genauigkeit sind fest eingeschrankt.
Wertebereiche sind nicht standardisiert! Typisch:
Ganzzahlig (Integer):
char: 1 Byte, −128 . . . 127
unsigned char: 1 Byte, 0 . . . 255
short int: 2 Byte, −32, 768 . . . 32, 767
int: 4 Byte, −2, 147, 483, 648 . . . 2, 147, 483, 647
Fließkomma (Real):
float: 4 Byte, ca. ±3.41038 bei 7 Dezimalstellen Genauigkeit
double: 8 Byte, ca. ±1.710308 bei 15 DezimalstellenGenauigkeit
Wahrheitswerte (Boolean):
bool: 1 Byte, “true” oder “false”
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Aufzahlungstypen
Aufzahlungen sind die einfachsten benutzerdefinierten Datentypen.Intern werden sie in der Regel als int gespeichert.
Beispiel
enum Wochentag {
montag , dienstag , mittwoch ,
donnerstag , freitag , samstag , sonntag
};
Wochentag heute = dienstag;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeichenketten
Zeichenketten (“Strings”) werden in "" eingeschlossen und internals char[] gespeichert. In C++ konnen Zeichenkettenkomfortabler mittels der string-Klasse verarbeitet werden.
Beispiel
#include <string >
using namespace std;
...
string hoersaal = "Hoersaal ";
string hallo = "Hallo " + hoersaal;
Wichtige Funktionen:
int n = s.length() (Große des Strings)
char c = s[i] (i-tes Zeichen)
string sub = s.substr(start,anzahl) (angegebenerTeilstring)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Konstanten
Konstanten werden mittels const definiert. Sie konnen wienormale Variablen benutzt werden, aber Anderungen werden vomCompiler verhindert.Syntax: const <Typname> <Variablenname> = <Wert>;
Beispiel
const double pi = 3.14159265;
const int maxIter = 500;
pi = -2; // Fehler zur Compilierzeit
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Benutzerdefinierte Typen
Mittels typedef lassen sich Bezeichner fur neue Typen festlegen.Syntax: typedef <Typbeschreibung> <NeuerName>;
Beispiel
typedef unsigned int Geldbetrag;
typedef long double WahnsinnigGrosseZahl;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Operatoren
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zuweisungsoperatoren
Der Zuweisungsoperator ist das einfache Gleichheitszeichen (=).Dem linken Operanden wird der Wert des rechten zugewiesen.
Beispiel
int a,b,c;
a = 1;
c = 2;
b = a = c; // b=1; a=1;
b = (a = c); // Zuweisungen haben einen Wert
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Arithmetische Operatoren
Arithmetische Operatoren sind auf ganzzahlige und reelleOperanden anwendbar. Eine Ausnahme bildet dieModulo-Operation %, die nur ganzzahlige Operanden erlaubt.
Mathematica
c = Plus[a,b]
c = Subtract[a,b]
c = Times[a,b]
c = Divide[a,b]
c = Mod[a,b]
C++
c = a + b;
c = a - b;
c = a * b;
c = a / b;
c = a % b;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Kombinierte Zuweisungsoperatoren
Zuweisungsoperatoren konnen mit einigen anderen Operatorenkombiniert werden:
Beispiel
/*************************************
* Kombinierte Zuweisungsoperatoren:
* += -= *= /= %= &= <<= >>= ^= |=
*************************************/
int a = 1;
a += 8; // a = 9
a *= 2 // a = 18
a %= 5 // a = 3
//ist die Alternative zu
a = 1;
a = a + 8; // a = 9
a = a * 2 // a = 18
a = a % 5 // a = 3
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Increment / Decrement
Um einen Operanden um 1 zu erhohen/vermindern kann derInkrement- bzw. Dekrement-Operator verwendet werden.Man unterscheidet
Postinkrement-/dekrement (a++, a--)Wert des Ausdrucks = ursprunglicher Wert der VariablenVariable hochzahlen/herunterzahlen
Prainkrement-/dekrement (++a, --a)Variable hochzahlen/herunterzahlenWert des Ausdrucks = veranderter Wert der Variablen
Beispiel
int a = 10;
cout << ++a << endl; // 11
cout << a-- << endl; // 11
cout << a << endl; // 10
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Logische Operatoren
Logische Operatoren liefern einen bool-Wert zuruck. Der rechteAusdruck wird nicht ausgewertet, wenn das Ergebnis nach derAuswertung des linken Ausdrucks schon feststeht!
Mathematica
b1 = True
b2 = False
r = And[b1 ,b2]
r = Or[b1 ,b2]
r = Not[b1]
C++
bool b1 , b2 , r;
b1 = true;
b2 = false;
r = b1 && b2;
r = b1 || b2;
r = !b1;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Bitweise Operatoren
Die bitweisen Operatoren sind anwendbar auf ganzzahligeDatentypen und arbeiten direkt auf der zugrundeliegendenBinardarstellung.
& bitweises AND
| bitweises OR
^ bitweises XOR (exklusives OR)
<< bitweises Linksschieben (shift left)
>> bitweises Rechtsschieben (shift right)
~ Einerkomplement (Negation)
Beispiel
int a=5, b=6,c;
c = a & b; // 4
c = a | b; // 7
c = a ^ b; // 3
c = a << 1; // 10
c = b >> 1; // 3
c = ~a; // -6
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Vergleichsoperatoren
Vergleichsoperatoren geben true oder false zuruck. Sie sind aufallen elementaren Datentypen definiert.
Mathematica
c = Equal [4,4]
c = Unequal [4,5]
c = LessEqual [4,4]
c = GreaterEqual [4,4]
c = Less [4,4]
c = Greater [4,2]
C++
bool c;
c = 4 == 4;
c = 4 != 5;
c = 4 <= 2;
c = 4 >= 4;
c = 4 < 4;
c = 4 > 2;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Vergleichsoperatoren
Verstanden?
Beispiel
int i1=4;
double d1=4, d2=2.5, d3=2.1;
float f2=2.5, f3 =2.1;
cout << (i1==d1) << endl;
cout << (d2==f2) << endl;
cout << (d3==f3) << endl;
Wie sieht die Ausgabe aus?
Ausgabe
110
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Vergleichsoperatoren
Verstanden?
Beispiel
int i1=4;
double d1=4, d2=2.5, d3=2.1;
float f2=2.5, f3 =2.1;
cout << (i1==d1) << endl;
cout << (d2==f2) << endl;
cout << (d3==f3) << endl;
Wie sieht die Ausgabe aus?
Ausgabe
110
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Prioritatentabelle
OPERATOREN AUSWERTUNG VON
01 :: links nach rechts
02 () [] -> . X++ X-- links nach rechts
typeid XXX_cast <TYPE >()
03 ! \~ ++X --X + - * \& (TYPE) rechts nach links
(TYPE) sizeof new delete
04 .* ->* links nach rechts
05 * / % links nach rechts
06 + - links nach rechts
07 >> << links nach rechts
08 < <= > >= links nach rechts
09 == != links nach rechts
10 & links nach rechts
11 ^ links nach rechts
12 | links nach rechts
13 && links nach rechts
14 || links nach rechts
15 = *= /= %= += -= rechts nach links
<<= >>= &= |= ^=
16 ?: rechts nach links
17 throw -
18 , links nach rechts
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Typumwandlungen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Typumwandlungen
Typumwandlungen (“type casts”) sind notwendig, wenn Datenunterschiedlichen Typs miteinander kombiniert werden mussen.
Beispiel
int teilnehmer = 50;
double gebuehr = 99.95;
double einahmen = teilnehmer * gebuehr;
Man unterscheidet
explizite Typumwandlungen und
implizite Typumwandlungen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Explizite Typumwandlungen
Syntax: (Typ) quelle
Beispiel
(double) 5 // 5.0 (exakt moeglich)
(int) 4.75 // 4 (wird zu 0 hin gerundet)
(unsigned char) (6*256+14) // 14
(int) true // 1
(int) false // 0
(bool) 0 // false
(bool) 44 // true (alles ausser 0 wird als
// true interpretiert)
(bool) -5 // true
Typumwandlungen in großere Typen (char → int, int →double) sind in der Regel problemlos.
Typumwandlungen in kleinere Typen (double → int, int →char) sind kritisch, auf Compilerwarnungen achten!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Implizite Typumwandlungen
Bei Ausdrucken mit gemischten Typen wandelt der Compilerautomatisch den kleineren in den großeren Typ um:
Beispiel
int teilnehmer = 50;
double gebuehr = 99.95;
double einahmen = teilnehmer * gebuehr;
// entspricht (( double) teilnehmer) * gebuehr
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Implizite Typumwandlungen
Bei den numerischen Datentypen wird bei einer Zuweisungautomatisch in den Datentyp der Zielvariablen umgewandelt:
Beispiel
double result = 42;
int teilnehmer = 55.4;
// entspricht int teilnehmer = (int) 55.4,
// Compiler gibt Warnung aus
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Implizite Typumwandlungen
Achtung, die Typumwandlung in den Zieldatentyp findet erst ganzzum Schluss statt:
Beispiel
double d = 3.0/4.0; // 0.75, keine implizite Umwandlung
double d = 3.0/4; // 0.75, entspricht 3.0/(( double) 4)
double d = 3/4.0; // 0.75, entspricht (( double) 3)/4.0
double d = 3/4; // 0.0 (!), entspricht (double )(3/4).
// Integer werden ohne Rest dividiert!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Felder
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Felder
Felder (“Arrays”) sind eine Aneinanderreihung von Elementengleichen Typs.
Zugriff auf die Elemente mittels x[i]. Das erste Element istx[0]!
Mehrere Dimensionen: m[i][j]
Syntax: <Typ> Name[<Anzahl>];
Beispiel
unsigned int teilnehmer [7]; // ein Eintrag pro Wochentag
Wochentag wochentage [31]; // auch kompliziertere Basis -
// typen sind moeglich
typedef double Matrix [3][3];
Matrix m;
m[1][0] = 1; // 2. Zeile , 1. Spalte
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Felder
Felder konnen nicht auf der linken Seite von Zuweisungen stehen.Ausnahme: Initialisierung.
Beispiel
int u[3];
u = {1,0,0}; // Fehler
int v[3] = {0,1,0}; // ok
int w[] = {0,0,1}; // ok, Groesse wird
// automatisch ermittelt
int m[3][3] = {{1,1,1},{0,1,2},{0,0,1}};
// ok , m[1][2] ist 2
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Felder – Fehlerquellen
Bei Zugriffen auf einzelne Elemente findet keine Uberprufung desIndex statt!
Beispiel
int x[10]; // 10 Elemente: x[0],...,x[9]
x[10] = 0; // compiliert , aber Laufzeitfehler
x[-1] = 0; // compiliert , aber Laufzeitfehler
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Listen
Fur die Verarbeitung komplexerer Datenstrukturen stehen in derSTL (Standard Template Library) viele Typen und Verfahren zurVerfugung.
Beispiel
#include <iostream >
#include <algorithm >
#include <vector >
using namespace std;
int op_square(int i) { return i*i; }
void op_print(int i) { cout << " " << i; }
int main(int argc , char** argv) {
vector <int > v, w;
for (int i = 1; i < 5; i++) v.push_back(i);
transform(v.begin(), v.end(), back_inserter(w), op_square );
for_each(w.begin(), w.end(), op_print );
cout << endl;
return EXIT_SUCCESS;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger
Variablenname
Ein Variablenname steht in C++ fur eine Speicheradresse. BeiOperationen mit Variablen wird automatisch mit dem Inhalt dieserAdresse gerechnet. Die Zuordnung Variable → Adresse wird zurCompilierzeit festgelegt.
Zeiger
Zeiger sind Variablen, die eine Adresse einer anderen Variablenspeichern, also auf andere Variablen verweisen konnen. BeiOperationen mit Zeigern wird mit den Adressen gerechnet. DerSpeicher, auf den ein Zeiger zeigt, kann sich zur Laufzeit andern.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger
Syntax:
Zeiger auf eine Variable bestimmen: & <Variable>
Variable, auf die ein Zeiger zeigt: * <Zeiger>
Zeiger haben einen eigenen Typ, der auch den Datentyp derzugrundeliegenden Variablen beschreibt:
Beispiel
unsigned int* zeigerAufInt;
typedef Wochentag* ZeigerAufWochentag;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Warum Zeiger?
Beispiel
int n = liesDimensionEin ();
// Feld der Groesse n erzeugen
double werte[n]; // Fehler
Problem: Die Adressen der Variablen werden zur Compilierzeitfestgelegt. Ohne deren Große zu kennen ist das aber unmoglich.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Dynamische Felder
Idee: Erst zur Laufzeit Speicher reservieren und nur den Zeigerdarauf in einer Variablen speichern.Syntax: <Variable> = new <Typ>[<Große>];
Beispiel
double* werte; // Zeigervariable
int n = liesDimensionEin ();
werte = new double[n]; // Speicher reservieren
werte[n-1] = 5; // letztes Element
*( werte + 1) = 0; // zweites Element
delete [] werte; werte = 0; // Speicher wieder freigeben
Achtung: Speicher nach dem Gebrauch immer wieder mitdelete[] freigeben!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger – Grundlagen
Mit Hilfe von Zeigern kann auf eine Variable uber mehrere Namenzugegriffen werden:
Beispiel
int a = 5;
int* b;
// a ist jetzt 5
b = & a;
*b = 4;
// a ist jetzt auch 4
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger – Grundlagen
Zeiger konnen auf einzelne Elemente eines Feldes zeigen:
Beispiel
double kaninchen [10];
double summe = 0;
double* p = &kaninchen [0]; // p zeigt auf das erste Element
// kurz: double* p = kaninchen;
for (int i = 0; i < 5; ++i) {
summe += *p;
++p; // p zeigt jetzt auf das
// naechste Element
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Zeiger
Beim Arbeiten mit Zeigern wird nicht uberpruft, ob sietatsachlich auf eine Variable zeigen.
Zeiger fuhren schnell zu Fehlern, die der Compiler nichterkennen kann, und die erst zur Laufzeit auftreten.
Beispiel
int* p = 0;
int b = *p; // ganz uebler Laufzeitfehler
int v[5];
p = v; // entspricht p = &v[0]
*(p+5) = 1; // sehr beliebt und sehr uebel
{
int a = 5;
p = &a;
}
*p = 4; // subtiler Fehler der kaum zu finden ist
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Referenzen
Uber Referenzen kann man einer Variablen einen Alternativnamengeben. Das Ziel einer Referenz wird direkt bei der Definitionfestgelegt und lasst sich hinterher nicht mehr andern.Syntax: <Zieltyp>& referenz = &<Ziel>;
Beispiel
int a = 5;
int& b = a;
// a ist jetzt 5
b = 4;
// a ist jetzt auch 4
Referenzen sind sicherer als Zeiger, aber nicht immer einsetzbar.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Verschiedenes
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Kommentare
// kommentiert bis zum Ende der Zeile aus:
Beispiel
double r = a / b; // b darf nicht 0 sein
/* und */ schließen einen mehrzeiligen Kommentar ein:
Beispiel
/* Diese Funktion testet , ob x eine Primzahl ist
* Eingabe: x
* Ausgabe: true wenn Primzahl , false wenn nicht
*/
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Ausgabe / Eingabe
Mathematica
Print ["Text"]
a = Input[]
C++
#include <iostream >
cout << "Text"; // Ausgabe
cin >> a; // Eingabe
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Schleifen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Schleifen
In C++ gibt es 3 verschiedene Schleifen:
for
while
do-while
ACHTUNG
Die do-Anweisungen in Mathematica und C++ habenunterschiedliche Bedeutung.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
For
Syntax :for(<initopt>; <expressionopt>; <updateopt>)<statement>
Mathematica
For[i = 1, i <= 10,
Print[i],
++i
];
C++
for(int i=1; i <=10; ++i) {
cout << i << endl;
}
Die Syntax der beiden for-Anweisungen ist sehr ahnlich. Andersals in Mathematica gibt es in C++ keine weiteren Syntaxvariantender for-Schleife.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
While
Syntax:while(<condition>) <statement>
Mathematica
a = 42;
While[a > 1,
a = a / 2
];
C++
double a = 42;
while (a > 1) {
a = a / 2.0;
}
Wie in Mathematica ist die while-Anweisung kopfgesteuert.Außer der etwas anderen Syntax gibt es keinen Unterschied.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Do-While
Syntax:do <statement> while (<condition>)
Mathematica
x = Input [];
While[x < 1 || x > 4,
x = Input[]
]
C++
double x;
cout << "x mit 1<=x<=4: ";
do {
cin >> x;
} while (x < 1 || y > 4);
Die do-while-Anweisung ist eine fußgesteuerte Schleife. InMathematica gibt es keine aquivalente Anweisung.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Kontrollstrukturen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
If
Syntax:if(<condition>) <statement1> else <statement2>
Mathematica
If[a > b,
Print[a],
Print[b]
]
C++
if (a > b) {
cout << a << endl;
} else {
cout << b << endl;
}
In C++ wird der Ausdruck, der ausgefuhrt wird, wenn dieBedingung nicht erfullt ist, mit dem Schlusselwort else eingeleitet.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Switch
Syntax:switch(<expression>){
case <constexpr1>:<statement1> break;
case <constexpr2>:<statement2> break;
...default:<statementn+1>
}
Achtung
In C++ wird jeder Befehl nach dem zutreffenden Fall ausgefuhrt,daher benotigt man break.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Switch
Mathematica
Switch[n,
0, "is zero",
1, "is one or two",
2, "is one or two",
_, "is different"
]
C++
switch(n) {
case 0:
cout << "is zero";
break;
case 1:
case 2:
cout << "is one or two";
break;
default:
cout << "is different ";
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Funktionen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Funktionen
Syntax:<Ruckgabetyp> <Funktionenname>(<Parameterliste>) {<Funktionenkorper>}return <Ausdruck>; beendet die Funktion und liefert den Wertdes Ausdrucks als Ruckgabewert der Funktion.
Mathematica
quadrat[x_] := x*x;
quadrat [5] (* 25 *)
quadrat [{1 ,2}] (* {1,4} *)
quadrat[a] (* a^2 *)
C++
int quadrat(int x) {
return x*x;
}
...
quadrat (5) // 25
int v[2] = {1,2};
quadrat(v) // Fehler
Der Typ jedes Arguments muss zur Compilierzeit feststehen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Funktionen
Eine Funktion muss keinen Wert zuruckgeben:
Beispiel
void anzeigen(int x) {
cout << x;
// kein return oder nur "return ;"
}
...
anzeigen (5); // ok
int i = anzeigen (5); // Fehler
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Funktionen
Funktionen haben immer einen Namen. Es gibt keine reinenFunktionen:
Mathematica
(1/# Sin [#])&[5]
C++
double f(double x) {
return 1.0/x * sin(x);
}
...
cout << f(5.0);
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Arten der Parameterubergabe
Erinnerung: Variablen stehen fur eine bestimmte Speicherstelle.Was passiert beim Aufruff(x); ?Parameter konnen auf zwei verschiedene Arten an die Funktionubergeben werden:
als Kopie des Inhalts der ubergebenen Variable (“pass byvalue”),
als Adresse bzw. Referenz auf die ubergebene Variable (“passby reference”).
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Pass by Value
Beispiel
double potenz(double x, double y) {
return exp(y*log(x));
}
...
double a = 15.0;
potenz(a,2);
Was passiert hier?
Der Wert an der durch a bezeichneten Speicherstelle wirdausgelesen, kopiert und an potenz ubergeben.
Der ganzzahlige Wert 2 wird in ein double konvertiert und anpotenz ubergeben.
Die Funktion hat keinen Einfluss auf den Wert ubergebenerVariablen außerhalb des Funktionenkorpers.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Pass by Reference
Beispiel
void tausche(double& x, double& y) {
double t = x;
x = y; y = t;
}
...
double a = 4.0; double b = 2.0;
tausche(a,b);
// jetzt ist a == 2.0 und b == 4.0
Die Adressen von a und b werden an die Funktion ubergeben.
Die Funktion kann Ergebnisse zuruckliefern, indem sieubergebene Variablen andert.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Pass by Reference
Und hier?
Beispiel
void tausche(double& x, double& y) { ... }
int quadrat(int x) { ... }
...
double a = 4.0;
tausche(a ,2.0); // Fehler
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Pass by Reference
Konstanten konnen nur als Wert ubergeben werden, da ihnen keineSpeicherzelle zugeordnet ist:
Beispiel
quadrat (5.5); // ok , aber mit Warnung
double a = 4.0; int b = 2;
tausche(a,b); // Fehler
“pass by reference” und implizite Typumwandlung schließen sichaus.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Wann Pass by Reference?
Faustregel:
Die Eingabe einer Funktion sollte als Wert ubergeben werden,um versehentliches Andern zu verhindern.
Die Ausgabe einer Funktion sollte mittels return oder per“pass by reference” zuruckgegeben werden.
Problem: Eingabeparameter mussen vor der Ubergabe kopiertwerden. Das kann bei komplizierten Datentypen langsam odernicht moglich sein.Losung: Konstante Referenzparameter.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Konstante Referenzparameter
Beispiel
void drucke(const KomplizierterTyp& was) {
...
}
Ubergabe per Referenz. Der Compiler uberwacht aber, dassdie Variable innerhalb der Funktion nicht verandert wird.
Bevorzugte Ubergabe fur Strings: const string& s
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sichtbarkeit, Gultigkeit undLebensdauer
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sichtbarkeit
Mathematica
c = 4;
f[x_] := c * x;
f[2] // -> 8
C++
int f(int x) {
return c * x; // Fehler
}
void main() {
int c = 4;
cout << f(2);
}
In C++ sind alle Variablen zunachst lokal, d.h. nur in ihrem Blocksichtbar. In Mathematica kann man ein ahnliches Verhalten mitModule erzwingen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Globale Variablen
Globale Variablen mussen explizit ausgewiesen werden:
Beispiel
int c;
int f(int x) {
return c * x; // ok
}
void main() {
c = 4;
cout << f(2);
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Verdeckung
Lokale Variablen verdecken globale Variablen:
Beispiel
int c = 4;
int f(int x) {
int c = 5;
return c * x; // entspricht 5 * x
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Blocke
Blocke kommen nicht nur in Funktionen vor, sondern immer, wenngeschweifte Klammern auftreten. Typisches Beispiel: Schleifen.
Beispiel
for (int i = 0; i < 5 && nichtZuGross(i); ++i) {
...
}
if (i >= 5) { // Fehler , i nicht definiert
// Schleife wurde nicht abgebrochen
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sichtbarkeit, Gultigkeit, Lebensdauer
Gultigkeitsbereich
Der Teil des Quelltextes, auf den sich die Deklaration bezieht, d.h.in dem prinzipiell uber den Namen auf die Variable zugegriffenwerden kann, solange sie nicht durch eine andere Deklarationverdeckt ist.
Sichtbarkeitsbereich
Der Teil des Quelltextes, in dem tatsachlich uber den Namen aufdie Variable zugegriffen werden kann.
Lebensdauer
Die Zeitspanne wahrend der Ausfuhrung, in der fur die VariableSpeicher reserviert ist.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sichtbarkeit, Gultigkeit, Lebensdauer
Lokale Variablen verdecken globale Variablen. Auf die globaleVariable kann man mittels ::<Variablenname> zugreifen.
Beispiel
a(1) a(2) a(3)
gs gs gs
int a = 2; // a(1) || .. ..
|| .. ..
void process(int x) { || .. ..
int a = 5; // a(3) |. .. ||
a = x; |. .. ||
::a = x; // global |. .. ||
} |. .. ||
|| .. ..
int main() { || .. ..
int a = 2; // a(2) |. || ..
process(a); |. || ..
return 0; |. || ..
} |. || ..
// Lebensdauer:
// a(1) ..[----------------------------]..
// a(2) .........[---------------]........
// a(3) ...............[ - - - - - -]...........
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Sichtbarkeit, Gultigkeit, Lebensdauer
Lokale Variablen konnen auch lokale Variablen verdecken. Auf dieverdeckten Variablen kann man dann nicht mehr zugreifen.
Beispiel
i(1) i(2)
gs gs
void func(int x[5]) { || ..
int i = 2; // i(1) || ..
for (int i = 0; // i(2) |. ||
i < 4; ++i) { |. ||
x[i] = i; |. ||
} |. ||
x[4] = i; || ..
} || ..
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Header
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Deklaration
Bevor ein Bezeichner verwendet werden kann muss er Deklariertwerden. D.h. es muss spezifiziert werden um was es sich dabeihandelt:
Beispiele
extern int fehler_nr;
class Test;
double berechne(int ,double );
char ch;
int count = 1;
enum Wasser{ Natur , Medium , Sprudel , Brackwasser };
Reine Deklarationen sind nur die ersten 3 Beispiele
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Definition / Initialisierung
Definition
Oft sind Deklarationen auch Definitionen. Definitionen definierenauch eine Entitat fur den Bezeichner (z.B. Speicherplatz odereinen Wert)
Initialisierung
Wir einem Bezeicher ein Wert zugewiesen, bezeichnen wir dies alsInitialisierung.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Header-Dateien
Header-Dateien werden mittels der Include-Direktive inC/C++-Quelltextdateien eingefugt. Sie definieren eineSchnittstelle fur alle Quelldateien. Den Inhalt von Header-Dateienbilden ublicherweise
die Vereinbarung von Makros und symbolischen Konstanten,
die Beschreibung der Aufrufschnittstelle von externenFunktionen,
die Klassendefinitionen
die Deklaration von nachnutzbaren Datentypen.
Daruberhinaus kann eine Header-Datei die Deklaration vonglobalen Variablen enthalten. Absolut unublich ist die direkteAufnahme von ausfuhrbaren Anweisungen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Einfugen von Header-Dateien in Quelltextdateien
Das einfugen von Header-Dateien kan mit dem Befehl #includebewerkstelligt werden. Fur Standardbibliotheken benutzt man diespitzen Klammern <> anstelle der Anfuhrungszeichen.
Beispiel
#include <iostream > // aus Standard -Include -Verzeichnis
#include ‘‘myheader.h’’ // aus aktuellem Verzeichnis
ACHTUNG
Leerzeichen bei einer #include-Direktiven sind inerhalb der <>bzw. ““ signifikant.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Mehrfaches Einfugen von Header-Dateien
Um das mehrfache Einfugenein und der selben Headerdatei zuverhindern, sollte jede Header-Datei in der Lage sein zu erkennen,ob sie bereits einmal eingefugt wurde. Dazu wird im Anfangsteilder Header-Datei eine symbolische Konstante definiert. Es kanndann abgefragt werden, ob diese symbolische Konstante bereitsexistiert.
Beispiel
#ifndef _myHeader_h_
#define _myHeader_h_
... Definitionen von myHeader.h ...
#endif _myHeader_h_
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenTypen Operatoren Cast Felder Zeiger Schleifen Kontrollstrukturen Funktionen Sichtbarkeit, Gultigkeit und Lebensdauer Header
Einsatzbeispiel Headerdateien
Beispiel
#ifndef _myDef_h_
#define _myDef_h_
enum Farben { rot , gelb , blau , gruen , braun };
enum Noten { 1, 2, 3, 4, 5};
enum Geschlecht { maennlich , weiblich };
enum Sprache { C, Cpp , Mathematica , Pascal };
Note wuerfelNote(Geschlecht );
Farbe waehleFarbe(Sprache );
#endif _myDef_h_
Besonders wichtig werden Header beim objektorientiertenProgrammieren in C++
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Kodierung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Kodierung von Zahlen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zahlensysteme
Definition
Ein Zahlensystem ist ein Tripel S = (b,Σ, δ) mit folgendenEigenschaften
b ≥ 2 ist eine naturliche Zahl und Basis des Zahlensystems
Σ ist eine Menge von b Symbolen, den Ziffern.
δ : Σ → {0, 1, . . . b − 1} ist eine bijektive Abbildung derZiffern auf die naturlichen Zahlen kleiner b einschließlich 0.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zahlensysteme
Beispiele
Dualsystem b = 2 Σ = {0, 1}Oktalsystem b = 8 Σ = {0, 1, 2, 3, 4, 5, 6, 7}Dezimalsystem b = 10 Σ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}Hexadezimalsystem b = 16 Σ = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,A,
B,C ,D,E ,F}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Umrechnung zwischen Zahlensystemen
Formel
< ab >=n−1∑i=0
δ(ai ) · bi
Beispiele
101012 = 1 · 24 + 1 · 22 + 1 · 20 = 2121 → x3 : (27, 9, 3, 1) 2 ∗ 9 + 1 ∗ 3 = 2103
2F16 = 1011112 = 578
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unterteilung
Festkommadarstellung
Zahlendarstellungen durch Betrag und Vorzeichen
Einer-/Zweierkomplement-Darstellung
Gleitkommadarstellung
IEEE-754 Format
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Festkommazahlen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Festkommazahlen
Definition
Eine Festkommazahl ist eine Folge von Ziffern eines Zahlensystems.Sie besteht aus n + 1 Vor- und k Nachkommastellen (n, k ≥ 0)
Eine nicht-negative Festkommazahl ist gegeben durch:
d = dndn−1 . . . d0 d−1 . . . d−k
wobei di ∈ Σ.Der Wert < d > einer Festkommazahl d ist gegeben durch
< d >=n∑
i=−k
bi · δ(di )
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Festkommazahlen
Schreibweise
Vor- und Nachkommastellen werden in der Regel zurVerdeutlichung mit einem Punkt oder Komma getrennt:
d = dndn−1 . . . d0 , d−1 . . . d−k
Um Mehrdeutigkeiten vorzubeugen wird die Basis desZahlensystem als Index angegeben:
1010s
Beispiele
d = 10102 < d >= 10 , d = 10, 012 < d >= 2, 25d = 10108 < d >= 520 , d = 14, 18 < d >= 14, 125d = 1416 < d >= 20 , d = 43, 25 < d >= 23, 4
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Negative Festkommazahlen
Fur den Fall b = 2
Beim Darstellen von negativen Zahlen nimmt die hochstwertigeStelle eine Sonderrolle ein. Ist dn+1 gleich 0 so handelt es sich umeine nicht-negative Zahl.
Darstellungsalternativen
Darstellung durch Betrag und Vorzeichen< [dn+1, dn, . . . , d−k ]BV >:= (−1)dn+1
∑ni=−k di2
i
Einer-Komplement Darstellung< [dn+1, dn, . . . , d−k ]EK >:=
∑ni=−k
[di · 2i
]− dn+1(2
n+1 − 2−k)Zweier-Komplement Darstellung< [dn+1, dn, . . . , d−k ]ZK >:=
∑ni=−k
[di · 2i
]− dn+12
n+1
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Betrag und Vorzeichen - Darstellung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Betrag und Vorzeichen
< [dn+1, dn, . . . , d−k ]BV >:= (−1)dn+1
n∑i=−k
di2i
Beispiel n=1, k=0
a 000 001 010 011 100 101 110 111
< [a]BV > 0 1 2 3 0 −1 −2 −3
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Betrag und Vorzeichen
Eigenschaften
Der Zahlenbereich ist symmetrisch
kleinste Zahl: −(2n+1 − 2−k)großte Zahl: (2n+1 − 2−k)
Man erhalt das additive Inverse durch Invertieren des erstenBits
2 Darstellungen fur 0
“Benachbarte Zahlen” haben Abstand 2−k
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Einer-Komplement - Darstellung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Einer-Komplement
< [dn+1, dn, . . . , d−k ]EK >:=n∑
i=−k
[di · 2i
]− dn+1(2
n+1 − 2−k)
Beispiel n=1, k=0
a 000 001 010 011 100 101 110 111
< [a]BV > 0 1 2 3 −3 −2 −1 0
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Einer-Komplement
Eigenschaften
Der Zahlenbereich ist symmetrisch
kleinste Zahl: −(2n+1 − 2−k)großte Zahl: (2n+1 − 2−k)
Man erhallt das additive Inverse durch invertieren aller Bits
2 Darstellungen fur 0
“Benachbarte Zahlen” haben Abstand 2−k
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zweier-Komplement - Darstellung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zweier-Komplement
< [dn+1, dn, . . . , d−k ]EK >:=n∑
i=−k
[di · 2i
]− dn+12
n+1
Beispiel n=1, k=0
a 000 001 010 011 100 101 110 111
< [a]BV > 0 1 2 3 −4 −3 −2 −1
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zweier-Komplement
Eigenschaften
Der Zahlenbereich ist unsymmetrisch
kleinste Zahl: −2n+1
großte Zahl: 2n+1 − 2−k
Man erhallt das additive Inverse durch invertieren aller Bitsund anschließendes addieren mit 2−k
Die Zahlendarstellung ist eindeutig
“Benachbarte Zahlen” haben Abstand 2−k
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Gleitkommadarstellung nach IEEE754
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Gleitkommadarstellung nach IEEE 754
Alternativ zur Festkommadarstellung wird bei derGleitkommadarstellung zusatzlich ein Exponent gespeichert der denZahlenbereich verschiebt und so eine moglichst gute Abdeckunggewahrleistet.
Einfache Genauigkeit:
31 30 29 28 . . . 24 23 22 21 20 19 . . . 4 3 2 1 0
S Exponent E Mantisse M
Doppelte Genauigkeit:
63 62 61 60 . . . 53 52 51 50 49 48 . . . 4 3 2 1 0
S Exponent E Mantisse M
Der Wert einer Zahl ergibt sich aus (−1)S ·M · 2E , wobei nochfestzulegen ist wie M und E interpretiert werden.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Normalisierte Mantisse nach IEEE 754
Beobachtung
0.01012 · 23 = 0.1010 · 22
Definition
Eine Gleitkommazahl (S,M,E) heißt normalisiert, wenn1 ≤ M < 2. M ware also in der Form 1.m−1m−2 . . .m−k . Diefuhrende 1 wird nicht abgespeichert und wird deshalb auch als“hidden bit” bezeichnet.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Exponent nach IEEE 754
Darstellung
Gemaß IEEE 754-Standard werden die Exponentenbits alsvorzeichenlose Zahl interpretiert.
Um auch negative Exponenten darstellen zu konnen wird dersogenannte Bias subtrahiert.
Bei n Exponentenbits betragt der Bias 2n−1 − 1, also 127 beieinfacher und 1023 bei doppelter Genauigkeit.
E berechnet sich also als∑n−1
i=0 ei · 2i − BIAS
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Sonderfalle im IEEE 754-Standard
Sind alle Bits des Exponenten 0, so ist auch das hidden bit 0.
Auf diese Weise konnen denormalisierte Zahlen dargestelltwerden, die kleiner sind als die kleinste darstellbarenormalisierte Zahl.Auf diese Weise kann auch die 0 dargestellt werden.
Sind alle Exponentenbits 1 und alle Mantissenbits 0, so wirdder Wert ±∞ dargestellt.
Sind alle Exponentenbits 1 und mindestens ein Mantissenbit1, so wird der Ausdruck “keine Zahl” dargestellt.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Addition von Gleitkommazahlen
Rechenvorschrift
1 Angleichen des kleineren an den großeren Exponenten
2 Addition der Mantissen unter Berucksichtigung desVorzeichens
3 Normalisieren und falls erforderlich Runden
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Multiplikation von Gleitkommazahlen
Rechenvorschrift
1 XOR auf das Vorzeichenbit
2 Multiplizieren der Mantissen
3 Addieren der beiden Exponenten und einmalig den Bias-Wertabziehen
4 Normalisieren und falls erforderlich Runden
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Zusammenfassung IEEE 754-Standard
single precision double precision
Vorzeichenstellen 1 1
Exponentenstellen 8 11
Mantissenstellen (ohne hidden bit) 23 52
Bitstellen ingesammt 32 64
Bias 127 1023
Exponentenbereich −126 bis 127 −1022 bis 1023
Darstellbare normalisierte Zahl mitkleinstem Absolutbetrag
2−126 2−1022
Darstellbare normalisierte Zahl mitgroßtem Absolutbetrag
(1− 224)2128 (1− 253)21024
Darstellbare denormalisierte Zahlmit kleinstem Absolutbetrag
2−149 2−1074
Darstellbare denormalisierte Zahlmit großtem Absolutbetrag
(41− 223)2126 (1− 252)21022
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Kodierung von Zeichen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
ASCII
Standard
Der ASCII-Standard existiert seit 1967 und definiert eine 7-bitKodierung von Zeichen. Zuletzt wurde es 1986 aktualisiert.Die Zeichen umfassen das lateinische Alphabet in Groß- undKleinbuchstaben, die zehn arabischen Ziffern sowie Satz undSteuerzeichen.Viele Zeichen wie z.B. Umlaute sind nicht darstellbar.
Kodierung
00 bis 1F sind Steuerzeichen
30 bis 39 die Ziffern 0 bis 1
41 bis 5A die Zeichen A bis Z
61 bis 7A die Zeichen a bis z
dazwischen liegen Klammern, Satzzeichen ...
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
ASCII
ASCII-Tabelle
! " # $ % & ’ ( ) * + , - . /0 1 2 3 4 5 6 7 8 9 : ; < = > ?@ A B C D E F G H I J K L M N OP Q R S T U V W X Y Z [ \ ] ^ _‘ a b c d e f g h i j k l m n op q r s t u v w x y z { | } ~
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
ASCII
Problem
Viele Zeichen ließen sich nicht darstellen, z.B. a, u, α, usw.
Losung?
Verwenden des freien Bits.Dies fuhrte zu dutzenden Zeichenkodierungen, die alle kompatibelzu ASCII waren aber nicht untereinander kompatibel. CP437 undISO 8859 gehoren hier zu den bekanntesten.Eine Losung war dies also nicht!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode
Standard
Unicode ist ein internationaler Zeichenkodierungs-Standard.
In ihm soll langfristig fur alle sinntragenden Zeichen bzw.Textelemente aller bekannten Schriftkulturen undZeichensysteme ein digitaler Code festgelegt werden.
Ziel ist es, das Problem unterschiedlicher, inkompatiblerKodierungen in unterschiedlichen Landern oder Kulturkreisenzu beseitigen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode
Standard
Das Unicode Consortium wurde 1991 gegrundet und ist furden Industriestandard Unicode verantwortlich.
Von der ISO wird die internationale Norm ISO 10646herausgegeben
Beide sind seit 1993 bezuglich der Zeichenkodierung identisch.
Gegenuber anderen Normen gibt es bei Unicode dieBesonderheit, dass einmal kodierte Zeichen niemals wiederentfernt werden, um die Langlebigkeit digitaler Daten zugewahrleisten.
Die unteren 256 Zeichen entsprechen der ISO8859-1-Kodierung (Latin1), andere ISO 8859-Kodierungensind i.d.R. komplett in einen hoheren Codebereich verschoben
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode
Standard
Der Standard Unicode 1.0 umfasste 16 Bit (= 65536 moglicheZeichen)
Zitat: ”16-bits wide because this provides a sufficient numberof codes (65,536) to represent electronic text charactersanticipated for the foreseeable future” (1991)
Der Standard Unicode 2.0 umfasste 24 Bit (1996)
Der momentante Standard Unicode 5.0 umfasst etwa 99.000Zeichen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode-Kodierung
UTF-8
Abk. fur 8-bit Unicode Transformation Format
Die am weitesten verbreitete Kodierung fur Unicode-Zeichen
Kodierung variabler Lange mit maximal 4 Byte
Unicode-Bereich UTF-8-Kodierung0000 0000-0000 007F 0XXXXXXX
0000 0080-0000 07FF 110XXXXX 10XXXXXX
0000 0800-0000 FFFF 1110XXXX 10XXXXXX 10XXXXXX
0001 0000-001F FFFF 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX
UTF-32
Abk. fur 32-bit Unicode Transformation Format
Kodierung mit fixer Lange (4 Byte)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenZahlensysteme FK GK Zeichen
Unicode
Ausblick
Dies war nur ein kleiner Einblick in den Unicode-Standard.
Unicode bringt auch viele neue Probleme mit sich.
Es gibt einen Unterschied zwischen Zeichen und Codepoint(hier ignoriert)
Combining-Characters und Compatibility characters →Normalisierung notwendig
BiDi-Classes
Vergleichen von Texten ist nicht trivial
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Stack
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Stack
Definition
Der Stack, auch Stapel- oder Kellerspeicher genannt, ist einSpeicherbereich fur Variablen, die schon zur Kompilezeit bekanntsind. Der Speicher muss in umgekehrter Reihenfolge derAnforderung freigegeben werden. Die Laufzeitkosten einerSpeicheranforderung sind geringer da kein System-Calldurchgefuhrt werden muss. Dafur ist der fur den Stack reservierteSpeicher beschrankt. Extensives Verwenden kann zumProgrammabbruch wegen Stapeluberlauf fuhren.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Stack
Vorteile
Hohe Geschwindigkeit (da keine System-Calls)
Effiziente Speichernutzung (da keine Fragmentierung)
Geringer Verwaltungsaufwand (LIFO)
Nachteile
Speicherplatz beschrankt (einstellbar Linux oft 8 MB)
Keine verschrankten Gultigkeiten
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Beispiele
Code
int f(int wert , int* zeiger ){
int add = 2;
int lokal = wert + 2
*zeiger = lokal;
return 2* lokal;
}
Beschreibung
Bei jedem Aufruf von f wird eine neue Schicht (frame) auf den Stackgelegt. Sie enthalt die lokalen Variablen (add, lokal), die Parameter(wert, zeiger) und eine Rucksprungadresse.Beim Verlassen, wird das frame entfernt, die Variablen vernichtet und derProgrammablauf bei der Rucksprungadresse fortgesetzt.Das Zerstoren der Variable zeiger hat keinen Einfluss auf den Speicher,auf den sie zeigt.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Heap
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Heap
Definition
Der Heap, auch Free Store, Halde, dynamischer Speicheroder Freispeicher genannt, ist ein Speicherbereich fur Variablen“unbekannter” Große. Speicherplatz kann in beliebiger Reihenfolgeangefordert und freigegeben werden.
Anmerkung
Der Begriff Heap ist traditionell bedingt und bezeichnet auch eineDatenstruktur. Die korrekte Bezeichnung in C++ ware FreeStore, gebrauchlich ist aber Heap.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Heap
Vorteile
Speicherplatz “voll” nutzbar
Gultigkeiten frei wahlbar
Nachteile
Allokieren von Speicher kostet mehr Zeit (da System-Callnotwendig)
Speicher kann fragmentieren
Speicherfreigabe muss selbst organisiert werden (C++)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Beispiele
Code
int f(int wert , int** zeiger ){
int* v = new int;
*v = wert+2
*zeiger = v;
return 2*(*v);
}
Beschreibung
Im Unterschied zu der Stack-Funktion, wird hier neuerSpeicherplatz fur ein Integer auf dem Heap reserviert und derPointer *zeiger auf diese Adresse gesetzt. Der Inhalt des von vreferenzierten Speichers bleibt im Heap auch nach Funktionsendebestehen bis er mittels delete freigeben wird.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Speicherlecks
ACHTUNG
Speicher den Sie mittels new anfordern mussen Sie auch wiedermittels delete freigeben.Ansonsten beansprucht Ihr Programm unnotig viel Speicher, deranderen Programmen nicht mehr zur Verfugung steht.
Im schlimmsten Fall steht am Ende ihrem eigenen Programm nichtmehr genug Speicher zur Verfugung und es kann nicht korrektfortgesetzt werden.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Fragmentierung
Was ist Fragmentierung?
Beim Anfordern eines Speicherbereiches mit new wirdgarantiert, dass der Adressraum der Variable zusammenhangt.
Beim Freigeben mit delete kann es passieren, dass Speicherzwischen belegten Adressraumen frei wird.
Diese Bereich kann nur fur Variablen die kleiner sind oder diegleiche Große haben verwendet werden.
Der Speicher ist also fragmentiert / verschnitten.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenStack Heap
Fragmentierung
Wird das Problem der Fragmentierung durch virtuelle Adressierungdes Speichers gelost?
In gangigen Architekturen hat jeder Prozess seinen eigenenAdressraum.
Das Umsetzten von physikalischen zu virtuellen Adressengeschieht auf der Ebene der Frames/Pages.
Dies lost großten teils das Problem der externeFragmentierung.
Virtueller Speicher kann auf 2 Weisen fragmentieren:
interne Fragmentierung: Seiten werden nicht ganz genutzt→ Speicher liegt brach.virtuelle Fragmentierung: Der virtuelle Adressraum kannfragmentieren → Es existieren nur noch kleinezusammenhangende Adressbereiche.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objektorientierung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Prozedural/Objektorientiert
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Aufgabe
Wir wollen unsere Rentiere in C++ verwaltenund dafur einen passenden Datentyp erstellen.Ein Rentier wird beschrieben durch:
den Name,
die Farbe des Fells (hell oder dunkel) und
das Alter.
Ein Rentier hat auch Operationen:
Name, Farbe und Alter auslesen,
Name andern,
uberprufen, ob man zweimal das gleicheRentier hat,
uberprufen, ob ein Rentier alter als einanderes ist,
Alter erhohen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Prozedurale Programmierung
Bisher haben wir prozedural programmiert, d.h. es gibt einerseitsDaten und andererseits Funktionen (“Prozeduren”), die die Datenverarbeiten:
Beispiel
enum Fell {hell , dunkel };
// Eine Rentier besteht aus
// - string name
// - Fell fell
// - int alter
// Bitte dran halten!
// Rentiere vergleichen
bool rentiereSindGleich(string name1 , Fell fell1 , int alter1 ,
int alter1 , string name2 , Fell fell2 , int alter2) {
return (name1 == name2) && (fell1 == fell2) && (alter1 == alter2 );
}
...
string rname = "Rudolf", aname = "Alice ";
Fell rfell = dunkel , afell = hell;
int ralter = 12, aalter = 9;
cout << rentiereSindGleich(rname ,rfell ,ralter ,aname ,afell ,aalter );
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Prozedurale Programmierung
Probleme:
urks
Der Benutzer des Datentyps muss sich um alle Detailskummern und wissen, wie ein Rentier intern verwaltet wird.
Schwierig zu erweitern: Um neue Felder einzufuhren (z.B.Große) muss der Benutzer das gesamte Programmumschreiben (→rentiereSindGleich).
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objektorientierte Programmierung
Beim objektorientierten Ansatz werden alle zu einem Datentypgehorenden Datenfelder (und spater auch die moglichenOperationen) in einem neuen zusammengesetzten Datentyp – einerKlasse – zusammengefasst.
Beispiel
class Rentier { // Klassenkopf
string name; // Klassenrumpf
Fell fell;
int alter;
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objekte
Variablen, die eine Klasse als Typ haben, nennt man Objekt (oderInstanz einer Klasse):
Beispiel
Rentier rudolf; // Rudolf ist ein Objekt
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objekte und Attribute
Jedes Objekt vom Typ Rentier hat einen eigenen Satz Variablenname, fell und alter. Diese Variablen werden Attribute (auch“Felder”) des Objekts rudolf bzw. der Klasse Rentier genannt.Mit dem Punkt . kann man auf die Attribute eines Objektszugreifen:
Beispiel
cout << rudolf.name;
rudolf.fell = dunkel;
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objekte und Attribute
Objekte kann man wie alle anderen Variablen auch dynamischerzeugen:
Beispiel
// Speicher reservieren , Objekt erzeugen und
// Zeiger darauf zurueckliefern.
Rentier* prudolf = new Rentier;
(* prudolf ).name = "Rudolf "; // Attribut aendern
delete prudolf; // Objekt zerstoeren , Speicher freigeben
objekt->attribut ist eine Kurzschreibweise fur(*objekt).attribut:
Beispiel
prudolf ->name = "Rudolf ";
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Objekte und Attribute
Objekte kann man kopieren:
Beispiel
Rentier rudolf , alice;
...
alice = rudolf; // Alle Komponenten werden kopiert
Alle Attribute werden dabei unverandert ubernommen. Vergleichenist aber nicht direkt moglich:
Beispiel
if (alice == rudolf) { ... } // Fehler beim Compilieren
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Schon besser!
Beispiel
bool rentiereSindGleich(Rentier a, Rentier b) {
return (a.name == b.name) && (a.fell == b.fell)
&& (a.alter == b.alter);
}
...
Rentier r,a; // Objekte erzeugen
r.name = "Rudolf "; a.name = "Alice"; // Attribute setzen
r.fell = dunkel; a.fell = hell;
r.alter = 12; a.alter = 9;
cout << rentiereSindGleich(r,a);
Aber: Man sollte einer Klasse auch ansehen konnen, welcheOperationen sie unterstutzt.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Methoden
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Methoden
Idee: Die zulassigen Operationen werden mit in dieKlassendefinition geschrieben:
Beispiel
class Rentier {
// Attribute
string name;
Fell fell;
int alter;
// Methoden
bool istGleich(Rentier r);
};
Bei der objektorientierten Programmierung werden Daten undOperationen in einer Klasse zusammengefasst.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Methoden
Eine Funktion innerhalb eine Klasse heißt Methode. Wenn man einObjekt hat, kann man uber den Punkt . darauf zugreifen:
Beispiel
Rentier r,a;
...
cout << r.istGleich(a);
Bei Zeigern auf Objekte wie bei den Attributen analog mit ->.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Methoden
Der Methodenrumpf wird separat mit der :: – Syntax festgelegt:
Beispiel
bool Rentier :: istGleich(Rentier r) {
...
}
Dadurch wird gekennzeichnet, dass diese Funktion zur KlasseRentier gehort. Methoden gleichen Namens aus unterschiedlichenKlassen storen sich nicht:
Beispiel
void Rentier :: fressen () { ... }
void Elefant :: fressen () { ... } // kein Problem
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zugriff auf Attribute
In einer Methode sind automatisch alle Attribute der zugehorigenKlasse bekannt:
Beispiel
bool Rentier :: istGleich(Rentier r) {
return
(name == r.name) &&
(fell == r.fell) &&
(alter == r.alter);
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
this
In Methoden kann uber die Variable “this” ein Zeiger auf dasObjekt ermittelt werden, zu dem die Methode gehort.
Beispiel
bool Rentier :: istGleich(Rentier r) {
// this ->attribus , (*this). attribut und attribut
return
(this ->name == r.name) &&
((* this).fell == r.fell) &&
(alter == r.alter);
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
this
Der this-Zeiger wird manchmal zur Ubergabe an andereFunktionen benotigt (→ Uberladen von Operatoren):
Beispiel
void druckeRentier(Rentier& r) {
cout << "Rentier " << r.name << endl;
}
bool Rentier :: zeigeName () {
druckeRentier (*this);
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zusammenfassung – Klassendefinition
Die Klassendefinition besteht aus der class-Anweisung undbeschreibt, was der Datentyp kann – also den Teil, an dem derBenutzer der Klasse interessiert ist (die “Schnittstelle”).
Beispiel
class Rentier {
// Attribute
string name;
Fell fell;
int alter;
// Methoden
bool istGleich(Rentier r);
bool aelterAls(Rentier r);
void altern(unsigned int jahre);
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zusammenfassung – Methodendefinitionen
Die Methodendefinitionen bestehen aus der eigentlichenImplementierung der Methoden und beschreiben, wie der Datentypintern organisiert ist – also den Teil, fur den der Entwickler derKlasse verantwortlich ist (die “Implementierung”):
Beispiel
bool Rentier :: aelterAls(Rentier r) {
return (alter > r.alter );
}
void Rentier :: altern(unsigned int jahre) {
alter += jahre;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Alles ok?
Beispiel
...
Rentier r; // Objekt erzeugen
r.name = "Rudolf "; // Attribute setzen
r.fell = dunkel;
r.alter = 12;
r.altern (1); // Methode aufrufen
cout << h.alter; // Attribut auslesen
r.alter = 2; // oha
Problem: Die Implementierungsdetails der Klasse sind fur denBenutzer sichtbar, bosartige Benutzer konnen ungultigeOperationen durchfuhren.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Kapselung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Definition
Kapselung bedeutet, dass die Komponenten (hier: Klassen) einesSoftwaresystems uber definierte Schnittstellen miteinanderkommunizieren. Die Implementierungsdetails einer Komponentesind nach außen hin unsichtbar und vor Zugriffen durch denAnwender geschutzt.Vorteile:
Verschiedene Implementierungen einer Komponente sindaustauschbar, solange sie dieselbe Schnittstelle anbieten.
Der Anwender kann sich auf die durch die Schnittstellegarantierte Funktionalitat verlassen, ohne dass er wissen muss,wie diese Funktionalitat implementiert ist.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Public und Private
Idee: Ein Objekt kann private Attribute und Methoden haben, dienur innerhalb der Methoden der Klasse sichtbar sind:
Beispiel
class Rentier {
private: // privat
Fell fell;
int alter;
public: // oeffentlich
string name;
...
void altern(unsigned int jahre);
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Public und Private
Der Benutzer kann jetzt keine ungultigen Operationen mehrdurchfuhren:
Beispiel
r.alter -= 2; // Fehler zur Compilierzeit
Aus den Methoden der Klasse kann man weiterhin auf das Attributzugreifen:
Beispiel
void Rentier :: altern(unsigned int jahre) {
alter += jahre; // ok obwohl alter privat ist
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Konstruktoren
Noch ein Problem:
Beispiel
Rentier r;
r.name = "Rudolf ";
r.fell = dunkel;
r.alter = 12; // nicht mehr moeglich
Man kann Rudolf jetzt auch nicht mehr initialisieren!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Konstruktoren
Losung: Konstruktoren sind spezielle Methoden, die beimErzeugen eines neuen Objekts aufgerufen werden und es in einendefinierten Zustand versetzen.
Beispiel
class Rentier { // ...
public:
Rentier(string _name , Fell _fell , int _alter );
}
Konstruktoren haben keinen Ruckgabewert. Definition:
Beispiel
Rentier :: Rentier(string _name ,Fell _fell ,int _alter) {
name = _name; fell = _fell; alter = _alter;
cout << "Hallo " << _name << "!" << endl;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Konstruktoren – Aufruf
Die Parameter fur den Konstruktor werden bei der Erzeugungneuer Variablen in Klammern () angegeben:
Beispiel
Rentier r(" Rudolf",dunkel ,12);
cout << r.name;
...
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Konstruktoren – Aufruf
Wenn eine Klasse einen Konstruktor hat, mussen die Parameter beider Erzeugung entsprechend gesetzt werden:
Beispiel
Rentier r(46.5); // Fehler zur Compilierzeit
Rentier r; // Fehler zur Compilierzeit (!)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Destruktoren
In manchen Fallen ist es notig, bestimmte Aktionen durchzufuhren,unmittelbar bevor der Speicher fur das Objekt wieder freigegebenwird. Diese Aufgabe ubernimmt der Destruktor:
Beispiel
class Rentier { // ...
public:
~Rentier ();
}
Rentier ::~ Rentier () {
cout << name << " wurde zerstoert ." << endl;
ersatz_besorgen ();
}
Destruktoren haben genau wie Konstruktoren keinen Ruckgabetyp.Sie haben aber keine Parameter und konnen nicht explizitaufgerufen werden!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Destruktoren
Beispiel
void zoo() {
Rentier rudolf (" Rudolf",dunkel ,12);
Rentier alice ("Alice",hell ,9);
...
}
Destruktoren werden in der umgekehrten Reihenfolge ausgefuhrt,in der die Objekte erzeugt wurden:
Ausgabe
Hallo Rudolf!
Hallo Alice!
Alice wurde zerstoert.
Rudolf wurde zerstoert.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Noch ein Problem
Warum?
Beispiel
Rentier r(" Rudolf",innen ,12);
cout << r.alter; // Fehler zur Compilierzeit
Problem: alter kann zwar nicht unerlaubt geandert werden, aberauch der Lesezugriff ist nicht mehr moglich!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Getter/Setter
Losung: Offentliche Methode bereitstellen, die Auslesenubernimmt (Getter):
Beispiel
class Rentier {
private:
int alter;
...
public:
int getAlter (); // Getter
};
int Rentier :: getAlter () {
return alter;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Getter/Setter
Zugriff:
Beispiel
Rentier r(" Rudolf",dunkel ,12);
cout << r.getAlter (); // geht , da oeffentliche Methode
r.alter = 2; // geht nicht , da privates Attribut
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Getter/Setter
Wie sieht es bei name aus? Hier ist auch eine Methode zum Setzennotig (Setter):
Beispiel
void Rentier :: setName(string _name) {
name = _name;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Inline
Man kann kurze Methoden (nicht nur Getter/Setter) direkt in dieKlassendefinition schreiben (“inline”):
Beispiel
class Rentier {
private:
string name;
public:
string getName () { return name; }; // Getter
void setName(string _name) { name = _name; }; // Setter
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Getter/Setter sind sinnvoll!
Es ist guter Programmierstil, grundsatzlich keine Attribute direktoffentlich zu machen und den Zugriff ausschließlich uberGetter/Setter zu ermoglichen. Der Entwickler der Klasse kann sospater
die interne Darstellung der Attribute andern oder
zusatzliche Aktionen beim Lesen/Schreiben hinzufugen,
ohne dass der Benutzer etwas davon merkt.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Getter/Setter sind sinnvoll!
Entwickler:
Beispiel
class Rentier {
private:
string vorname , nachname;
public:
string getName () {
return vorname + nachname;
}
void setName(string _name) {
vorname = ""; nachname = _name; // kompatibel bleiben
druckeUrkunde(vorname , nachname ); // neue Urkunde drucken
}
}
Benutzer:
Beispiel
Rentier r;
r.setName (" Rudolf ");
cout << r.getName (); // funktioniert noch genau wie frueher
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Uberladen von Operatoren
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Motivation
Problem:
Beispiel
if (r.istGleich(a)) { ... }
ist nicht sehr schon. Eleganter ware
Beispiel
if (r == a) { ... }
Der Compiler kann aber nicht wissen, was Gleichheit bei diesemDatentyp bedeutet!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Syntax
Man kann es dem Compiler explizit vorschreiben:
Beispiel Vergleichsoperator
class Rentier {
public:
// true bei Gleichheit , sonst false
bool operator ==( Rentier r) {
return istGleich(r);
}
}
...
if (r == a) { ... } // Aufruf: if (r.operator ==(a)) { ... }
Der Vergleichsoperator = wird “uberladen” durch eine spezialisierteVariante. Analog fur !=,<,>,<=,>= usw.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Syntax
Unare Operatoren (!,++,--,+=,*= usw.):
Beispiel
Rentier& Rentier :: operator ++() { // -- auch moeglich
altern (1);
return *this; // der ++ - Operator gibt das Objekt zurueck!
}
...
++ rudolf; // Aufruf: rudolf.operator ++();
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Syntax
Binare Operatoren (+,-,*,/ usw.):
Beispiel
Rentier Rentier :: operator *( Rentier r) {
return Rentier(getName () + "/" r.getName(),hell ,0);
}
...
ra = r * a; // Aufruf: ra = r.operator *(a);
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Syntax
Bei Klassen, die zur Laufzeit Speicher anfordern, muss haufig auchder Zuweisungsoperator uberladen werden (→ Ubung):
Beispiel
Rentier& operator =( Rentier& r) {
name = r.name;
...
cout << r.name << " wurde kopiert !" << endl;
return *this; // Objekt selbst ist Wert der Zuweisung
}
...
r = a; // Aufruf: r.operator =(a)
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Der Prozessor selbst unterstutzt keine Methodenaufrufe. DerCompiler muss also intern Methoden durch konventionelleFunktionen ersetzen:
Objektorientiert
void Rentier :: altern(
unsigned int jahre) {
alter += jahre;
}
...
rudolf.altern (1);
Intern
void Rentier_altern(
Rentier* this ,
unsigned int jahre) {
this ->alter += jahre;
}
...
Rentier_altern (&rudolf , 1);
Man konnte auch direkt so programmieren, aber dieOO-Schreibweise ist kurzer und praziser (public/private,Operatoren usw.).
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Vererbung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Wir wollen Rentiere in einer Herde verwalten.
Ein Herdenrentier soll alles konnen, was ein normales Rentierkann.
Zusatzlich soll es ein Attribut zum Speichern des Alphatierssowie die zugehorigen Getter/Setter besitzen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Beispiel
class HerdenRentier {
private: ...
public:
// neue Methoden
HerdenRentier(string _name , Fell _fell ,
int _alter , Rentier* _alpha );
void setAlpha(Rentier* _alpha );
Rentier* getAlpha ();
// von Rentier uebernommene Methoden
string getName () { return name; };
void setName(string _name) { name = _name; };
... usw. ...
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Redundanter Code
Problem: Alle Funktionen des Datentyps Rentier mussen erneutimplementiert werden. Redundanter Code ist
fehleranfallig: Tippfehler, Copy & Paste.
wartungsintensiv: Eventuelle Fehler mussen in allen Kopienkorrigiert werden.
schwierig zu erweitern: Bei Anderungen an derImplementierung mussen alle Kopien geandert werden.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Vererbung
Idee: Der Datentyp HerdenRentier erbt alle Attribute undMethoden des Datentyps Rentier. Dem Compiler wird dieserZusammenhang mitgeteilt!
Beispiel
class HerdenRentier : public Rentier {
private:
Rentier* alpha;
public:
// nur noch neue Methoden
HerdenRentier(string _name , Fell _fell ,
int _alter , Rentier* _alpha );
void setAlpha(Rentier* _alpha) { ... };
Rentier* getAlpha () { ... };
};
Rentier rudolf (" Rudolf",dunkel ,12);
HerdenRentier helga (" Helga",hell ,6,& rudolf );
cout << helga.getName (); // ok , geerbte Methode
helga.setAlpha (& rudolf ); // ok , neue Methode
public kennzeichnet, dass alle public Attribute und Methodender vererbenden Klasse weiterhin public sein sollen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Vererbung
Bei der Vererbung mit public werden alle
offentlichen und nicht-offentlichen Attribute
offentlichen und nicht-offentlichen Methoden (mit Ausnahmeder Konstruktoren)
einschließlich der Implementierungen ubernommen.Die vererbende Klasse heißt Basisklasse, die erbende Klasseabgeleitete (oder Sub-)Klasse.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zugriffssteuerung
Auf private Attribute/Methoden der Basisklasse kann nichtzugegriffen werden:
Beispiel
class HerdenRentier : public Rentier {
public:
void kaempfen () {
// Fehler , name ist private in Rentier
cout << name << " ist Pazifist ." << endl;
}
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zugriffssteuerung
Attribute und Methoden mit dem Schlusselwort protected sindwie bei private nach außen hin unsichtbar. Innerhalb vonMethoden der Klasse und aller abgeleiteten Klasse kann aberdarauf zugegriffen werden:
Beispiel
class Rentier {
protected: // (!)
string name;
public: ...
};
class HerdenRentier : public Rentier {
public:
void kaempfen () {
cout << name << " ist Pazifist ." << endl; // ok
}
};
HerdenRentier helga (...);
helga.name = "Alice "; // Fehler , name ist nicht public
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Zugriffssteuerung
Zusammenfassung
Zugriff aus... public protected private
Methode der Klasse selbst ja ja jaMethode einer abgeleiteten Klasse ja ja neinBenutzer der Klasse ja nein nein
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Vererbung und Konstruktoren
Konstruktoren werden nicht vererbt! Man muss explizit angeben,mit welchen Parametern der Konstruktor der Basisklasseaufgerufen werden soll:
Beispiel
HerdenRentier :: HerdenRentier(string _name , Fell _fell ,
int _alter , Rentier* _alpha)
: Rentier(_name ,_fell ,_alter) // Konstruktor der Basisklasse
// wird aufgerufen
{
alpha = _alpha; // zusaetzliche Initialisierung
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Uberschreiben von Methoden
Abgeleitete Klassen konnen auch das Verhalten geerbter Methodenandern, d.h. geerbte Methoden uberschreiben. Die Signatur derMethode (Anzahl und Typ der Parameter, Typ des Ruckgabewerts)andert sich dabei nicht.
Beispiel
class Rentier {
public:
void fressen () {
cout << getName () << " frisst ." << endl;
}
};
class HerdenRentier : public Rentier {
public:
void fressen () { // fressen wird ueberschrieben
cout << "Warte auf " << alpha ->getName () << "..."<< endl;
Rentier :: fressen (); // geerbte Methode aufrufen
}
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Typkompatibilitat bei Vererbung
Abgeleitete Klassen sind zur Basisklasse kompatibel und werdenbei Bedarf implizit in den Typ der Basisklasse umgewandelt. Dasist moglich, da der Compiler garantiert, dass alle Methoden undAttribute der Basisklasse in der abgeleiteten Klasse ebenfallsvorhanden sind.
Beispiel
void druckeRentier(Rentier& r) {
cout << "Rentier " << r.getName () << endl;
}
...
Rentier rudolf (...);
rudolf = helga; // ok , entspricht (Rentier)helga
HerdenRentier helga (...);
druckeRentier(helga ); // ok, ebenfalls implizite Umwandlung
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Typkompatibilitat bei Vererbung
Bei der Typumwandlung in einen Basistyp geht die zusatzlicheFunktionalitat verloren:
Beispiel
void druckeRentier(Rentier& r) {
// Fehler , Rentier enthaelt getAlpha () nicht
cout << (r.getAlpha ())->getName ();
}
...
HerdenRentier helga (...);
druckeRentier(helga ); // ok, implizite Umwandlung
Der Compiler kennt zur Compilierzeit den genauen Typ des in rubergebenen Objekts nicht. Er kann deshalb nur die Methoden ausRentier erlauben, obwohl das ubergebene Objekt mehr leistenkonnte.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Was passiert hier genau?
Objektorientiert
class Rentier { ...
void fressen () {
cout <<name <<" frisst .";
}
};
class HerdenRentier
: public Rentier {
void fressen () {
cout <<name
<<" wartet und frisst .";
}
};
Rentier r(...);
HerdenRentier h(...);
r.fressen ();
h.fressen ();
Intern
void Rentier_fressen(
Rentier* this) {
cout <<name <<" frisst .";
}
void HerdenRentier_fressen(
HerdenRentier* this){
cout <<name
<<" wartet und frisst .";
}
...
...
Rentier_fressen (&r);
HerdenRentier_fressen (&h);
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Und hier?
void fuettern(Rentier& r) {
r.fressen ();
}
Rentier rudolf (...);
HerdenRentier helga (...);
fuettern(rudolf );
fuettern(helga );
Ausgabe
Rudolf frisst.
Helga frisst.
Es wird nicht die Methode fressen() der abgeleiteten KlasseHerdenRentier, sondern die der Basisklasse Rentier aufgerufen!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Laufzeitpolymorphie
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Der Compiler entscheidet normalerweise zur Compilierzeit anhanddes Typs der Variable, welche Methode aufgerufen wird:
Objektorientiert
void fuettern(Rentier& r) {
r.fressen ();
}
...
HerdenRentier helga (...);
fuettern(helga );
Intern
void fuettern(Rentier& r) {
Rentier_fressen (&r); //(!)
}
...
...
fuettern (( Rentier &)& helga);
Bei der Typumwandlung in die Basisklasse geht also nicht nur dieneue Funktionalitat, sondern auch geanderte Funktionalitatverloren!
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Laufzeitpolymorphie
Definition
Laufzeitpolymorphie bedeutet, dass bei einem Methodenaufruf dietatsachlich aufgerufene Implementierung vom Typ des Objektsabhangt, das in einer Variable gespeichert ist, anstatt vom Typ derVariable. Diese Entscheidung kann erst zur Laufzeit getroffenwerden, denn Typ des Objekts ist zur Compilierzeit noch nichtbekannt!
Laufzeitpolymorphie ist neben Kapselung und Vererbung eine derwichtigsten Eigenschaften objektorientierter Programmiersprachen.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Laufzeitpolymorphie
C++ unterstutzt die Laufzeitpolymorphie mittels virtuellerMethoden und dem Schlusselwort virtual.
Beispiel
class Rentier {
public:
virtual void fressen (); // virtuelle Methode
};
// kein virtual in der Methodendefinition noetig
void Rentier :: fressen () {
cout << name << " frisst virtuell ." << endl;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Laufzeitpolymorphie
Beim Uberschreiben geerbter virtueller Methoden sollte dasSchlusselwort virtual immer mit angegeben werden, um denspeziellen Charakter deutlich zu machen:
Beispiel
class HerdenRentier : public Rentier {
public:
virtual void fressen (); // virtuelle Methode ueberschreiben
};
void HerdenRentier :: fressen () {
cout << name << " wartet und frisst virtuell."<< endl;
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Laufzeitpolymorphie
Die Adresse, an die beim Aufruf einer virtuellen Methodegesprungen wird, wird erst zur Laufzeit aufgelost:
Beispiel
void fuettern(Rentier& r) {
r.fressen ();
}
...
Rentier rudolf (...);
HerdenRentier helga (...);
fuettern(rudolf );
fuettern(helga );
Ausgabe
Rudolf frisst virtuell.
Helga wartet und frisst virtuell.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Wie kann das funktionieren? Wahrend des Compilierens vonfuettern kann der Compiler noch nicht wissen, welchen Typgenau das ubergebene Objekt haben wird!Idee:
Objekte enthalten eine Tabelle, in der die Adressen dervirtuellen Methoden gespeichert werden (“vtable”). BeimAufruf einer Methode wird zur Laufzeit die Adresse derFunktion aus der Tabelle bestimmt und diese dann aufgerufen.
Abgeleitete Klassen enthalten zunachst dieselbe Tabelle. Wirdeine virtuelle Methode uberschrieben, wird die entsprechendeAdresse in der Tabelle geandert.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Interne Umsetzung
Beispiel
const int FRESSEN_ID = 0;
const int Rentier_N = 1; // Anzahl virtueller Methoden
const int HerdenRentier_N = Rentier_N;
class Rentier {
(Zeiger_auf_Funktion) vtable[Rentier_N ]; // Tabelle virtueller Funktionen
};
void Rentier_fressen(Rentier* this) { ... }
class HerdenRentier {
(Zeiger_auf_Funktion) vtable[HerdenRentier_N ];
};
void HerdenRentier_fressen(HerdenRentier* this) { ... }
// setzt rudolf.vtable[FRESSEN_ID] auf die Adresse von Rentier_fressen
Rentier rudolf (...);
// setzt helga.vtable[FRESSEN_ID] auf die Adresse von HerdenRentier_fressen
HerdenRentier helga (...);
Rentier& rhelga = helga; // Typumwandlung auf Basistyp , vtable wird uebernommen!
// Aufruf rhelga.fressen(), bestimmt zunaechst die Adresse der
// Methode aus der Tabelle virtueller Funktionen von rhelga.
zeiger_auf_fressen = rhelga.vtable[FRESSEN_ID ];
// Die Funktion , auf die der Zeiger zeigt , wird dann augerufen.
zeiger_auf_fressen (& rhelga );
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Virtuell oder nicht?
Wann sollten Methoden virtuell sein?
Immer, wenn die Moglichkeit besteht, dass die Methode ineiner abgeleiteten Klasse uberschrieben wird.
Haufig nicht notig bei einfachen Gettern/Settern.
Der einzige Vorteil einer nicht virtuellen Methode ist ein etwasschnellerer Aufruf, da die Adresse der Methode nicht erst zurLaufzeit der vtable entnommen werden muss. In einigenSprachen (z.B. Java) sind grundsatzlich alle Methoden virtuell.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Abstrakte Klassen
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Wir wollen unseren Zoo verwalten:
Ein Zoo besteht aus mehreren Tieren,
man kann Tiere hinzufugen und
man kann alle Tiere futtern.
Problem: Wie sollen die Tiere gespeichert werden? ZurCompilierzeit ist noch nicht bekannt, welchen Typ genau die Tierehaben werden.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Idee:
Alle Tierklassen werden von der Klasse Tier abgeleitet.Innerhalb von Zoo konnen die Tiere in Variablen des TypsTier gespeichert werden.
Tier beschreibt wichtige Methoden, die allen Tieren gemeinsind.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Beispiel
class Tier {
private:
string name;
int alter;
public:
Tier(string _name , int _alter );
string getName () { return name; };
void setName(string _name) { name = _name; };
int getAlter () { return alter; };
virtual void altern(unsigned int jahre) {
alter += jahre;
}
virtual void fressen ();
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Die einzelnen Tiere mussen dann nur noch Methoden fur dieBesonderheiten zur Verfugung stellen.
Beispiel
class Rentier : public Tier {
private:
Fell fell;
public:
Rentier(string _name , Fell _fell , int _alter)
: Tier(_name , _alter) { // geerbeter Konstruktor
fell = _fell;
}
Fell getFell () { return fell; };
void setFell(Fell _fell) { fell = _fell; };
virtual void fressen () {
cout << "Rentier " << getName () << " frisst ." << endl;
}
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Beispiel
class Zoo {
private:
Tier* tiere [10];
...
public:
void setTier(int index , Tier& tier) {
tiere[index] = &tier;
}
Tier& getTier(int index) {
return *( tiere[index ]);
}
void fressen ();
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Fallbeispiel
Der Zoo kann dann die virtuelle Funktion fressen aufrufen:
Beispiel
void Zoo:: fressen () {
for (int i = 0; i < anzahl; ++i) {
tiere[i]->fressen ();
}
}
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Problem
Beispiel
class Tier { ...
public:
...
virtual void fressen (); // Implementierung fehlt!
};
Es ist sinnlos, ein Objekt vom Typ Tier zu erzeugen, denn“das Tier” existiert nicht. “Tier” ist vielmehr eineBeschreibung der gemeinsamen Eigenschaften mehrererKlassen.
Es gibt keine Implementierung von fressen, die fur alle Tieresinnvoll ist.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Abstrakte Klassen und rein virtuelle Funktionen
Virtuelle Funktionen konnen rein sein, d.h. keine Implementierungbesitzen:
Beispiel
class Tier { ...
public:
...
virtual void fressen () = 0; // rein virtuelle Funktion
};
Klassen, die reine virtuelle Funktionen enthalten, heißen abstrakt.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Abstrakte Klassen
Man kann keine Objekte erzeugen, die eine abstrakte Klasse alsTyp haben:
Beispiel
class Tier {
virtual void fressen () = 0; // rein virtuelle Funktion
virtual bool warmblueter () = 0; // dito
};
class Reptil : public Tier {
virtual bool warmblueter () { return false; }
};
class Krokodil : public Reptil {
virtual void fressen () { cout << "schnapp ."; };
};
Tier tier; // Fehler , Tier ist eine abstrakte Klasse
Reptil reptil; // Fehler , Reptil ist noch abstrakt da
// fressen () nicht ueberschrieben wurde
Krokodil krokodil; // ok
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Wann abstrakte Klassen?
Abstrakte Klassen sollten dann verwendet werden, wenn einegemeinsame Schnittstelle mehrerer Klassen beschrieben werdensoll, ohne deren Implementierung vorwegzunehmen.
Beispiel
class Darstellbar {
virtual void zeichneAuf(Bild& bild) = 0;
};
class Drucker {
virtual void drucke(string text) = 0;
};
class Reell {
virtual bool istNegativ () = 0;
};
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung LinkenAllgemeines Methoden Kapselung Kapselung Uberladen von Operatoren Vererbung Laufzeitpolymorphie Abstrakte Klassen
Literatur
Lahres, Rayman: Praxisbuch Objektorientierung. Volltext:http://www.galileocomputing.de/openbook/oo/(sehr ausfuhrlich und gut strukturiert, Beispiele in Java).
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Linken
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Linken
Hintergrund
Die Kapselung in Klassen ermoglicht es, jede Klasse fur sichzu entwickeln und zu compilieren.
Jede Klasse besteht dann aus einem Header(Klassendefinition) und dem Quellcode(Methodendefinitionen).
Beim Compilieren einer einzelnen Klasse wird eine Objektdateierzeugt. Sie enthalt den Maschinencode und eine Liste mitden Adressen der enthaltenen Methoden und Variablen.
Beim Linken werden die einzelnen Objektdateien verbunden,dabei werden symbolische Adressen aufgelosst.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Linken - Header
Wenn die Klassen A und B getrennt compiliert werden, weißder Compiler beim Ubersetzen von A nichts uber B.
Wenn A mit B interagiert, muss der Compiler aber zumindestdie Schnittstelle von B kennen, um eine Syntaxprufungdurchfuhren zu konnen. Die Implementierung von B istdagegen unwichtig.
Die Klassendefinition (class { ... };) von B wird deshalbin eine Headerdatei, z.B. B.h, ausgelagert.
Die Headerdatei wird mittels #include im Quellcode von Aeingebunden.
Die Implementierung von B befindet sich in einer getrenntenDatei B.cpp, die ebenfalls B.h einbindet.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Linken - Beispielheader
Beispiel
#ifndef _Account_h_
#define _Account_h_
class Account {
private:
double balance;
public:
double getBalance ();
double deposit(double amount );
double withdraw(double amount );
};
#endif /* _Account_h_ */
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++
Ubersicht Comp.-A. Grundl. Sprache Kodierung Stack/Heap Objektorientierung Linken
Linken - Header
Wird die Implementierung von B geandert, ohne dass dieKlassendefinition im Header geandert werden muss, muss dieKlasse A nicht neu compiliert werden! Es genugt, B.cpp neuzu compilieren und das Ergebnis neu zu linken.
Solange die Header kompatibel bleiben, konnen die Klassen Aund B getrennt entwickelt werden.
Jan Lellmann, Jorg Hendrik Kappes Einfuhrung in C++