Material zum C++ Crash Course / PROG3
© 2021–2023 | Stefan Röttger |
PROG3/B
C++ Crash Course
Voraussetzungen: Kenntnisse in C (PROG1&2)
Benötigt wird: Rechner mit Ubuntu
Inhaltsverzeichnis
Organisatorisches
- Discord-Installation (nicht für VirtualBox): snap install discord
- Gesamtprotokoll: Word-Vorlage
- Bestehen: Durch erfolgreiche Abgabe des Gesamtprotokolls aller Ãœbungsaufgaben
Einführung
Ziel des Kurses ist nicht C++ perfekt programmieren zu können. Ziel ist es vielmehr C++ Programme lesen bzw. verstehen zu können und die folgenden fünf grundlegenden C++ bzw. OO-Programmierprinzipien anwenden zu können:
- Datenkapselung
- Ableiten
- Spezialisieren
- Aggregieren
- Templates
Zu diesem Ziel wird jeweils in der Vormittags-Demo entsprechender Code exemplarisch entwickelt und die angewandten Prinzipien erläutert. In der Nachmittags-Übung wenden Sie anhand eines ähnlichen Beispiels die Prinzipien selber an. Wir verwenden dazu den C++11 Standard.
Tag #1
Themen #1:
- OO (Objekt-Orientierte Programmierung)
- Klassen
- Objekt und Zustand (am Beispiel eines Spielzeugs)
- Bauplan und Instantiierung (am Beispiel Button)
- Instanzvariablen (Members)
- Konstruktoren
- Datenkapselung und Zugriffskontrolle
- Zugriffsfunktionen (Methoden)
- Instanzvariablen vs. lokale Variablen und Parameter
- OO-Literatur und weiteres Material siehe Skript
- OO-Spezialitäten bei C++
- Prototypen und Implementierung (am Beispiel Uhrwerk)
- Namespace Operator ::
- Ãœberladen und Standardwerte
- statische Instanzvariablen und Methoden
- Destruktoren
- operator << (iostream)
Videos #1
werden hier hochgeladen
Teil | Video | Thema |
---|---|---|
1.1 | YT | OO Einführung |
1.2 | YT | Klassen und Objekte |
1.3 | YT | OO-Spezialitäten |
1.4 | YT | Ãœbungsvorbereitung #1 |
Ãœbung #1
- Der Code für die Übungen wird per Git herunter geladen:
- git clone https://github.com/roettger71/ccc.git
- Die heruntergeladene ZIP-Datei exc1.zip wird mit “unzip exc1.zip” entpackt, wobei ein Passwort eingegeben werden muss. Dieses wird hier bekanntgegeben:
- Passwort #1: 064379d4
- Der Code lässt sich mit “cmake . && make” übersetzen.
- Schreiben Sie nun auf dieser Codebasis eine Klasse Account, welches ein Konto mit einem gewissen Kontostand repräsentiert.
- Implementieren Sie den Konstruktor, so dass anfangs der Kontostand 0 ist und ein Kontrolltext ausgegeben wird.
- Implementieren Sie zusätzlich die folgenden Zugriffsmethoden:
- deposit(…) → zahlt einen Betrag auf das Konto ein
- withdraw(…) → hebt einen Betrag vom Konto ab (nur wenn genug Guthaben vorhanden ist, in diesem Fall soll außerdem der Wahrheitswert true zurückgegeben werden)
- balance() → liefert den aktuellen Kontostand zurück
- Testen Sie Ihre Klasse, indem Sie 5x 100 EUR einzahlen und 3x 150 EUR abheben und danach den Kontostand ausgeben. Der Kontostand muss danach 50 EUR betragen.
- Geben Sie den Kontostand in main() zurück. Dieser kann auf der Kommandozeile mit “echo $?” ausgegeben werden.
- Notieren Sie das Ergebnis im Gesamtprotokoll. Dazu fügen Sie einen Screenshot des obigen Programmablaufs auf der Kommandozeile ein. Beantworten Sie ebenfalls die Fragen der Lernzielkontrolle kurz und knapp im Protokoll.
Lernzielkontrolle:
- Was ist die Haupteigenschaft einer Klasse?
- In welcher Datei werden Klassen deklariert?
- In welcher Datei werden Methoden implementiert?
- Erklären Sie stichpunktartig die folgenden Fachbegriffe aus obiger Themenliste:
- 1.2 1.3 1.4 1.5 1.6 2.1 2.2 2.4
- Am besten anhand eines kurzen konkreten Beispiels!
Tag #2
Themen #2:
- Vererbung
- Ableitungen
- Ãœberschreiben und Spezialisieren (am Beispiel PushButton)
- Klassen und Polymorphismen
- Basisklassen und Initializer Lists
- Virtuelle Methoden
- [Mehrfachvererbung]
- [Call-By-Name]
- Templates
- Header-only Klassen
- Templatisierte Klassen (am Beispiel von Arrays)
- [Dynamische Arrays als Template]
Videos #2
werden hier hochgeladen
Teil | Video | Thema |
---|---|---|
2.1 | YT | Vererbung |
2.2 | YT | Spezialisieren |
2.3 | YT | Templates |
2.4 | YT | Ãœbungsvorbereitung #2 |
Ãœbung #2
- Die heruntergeladene ZIP-Datei exc2.zip wird entpackt, wobei ein Passwort eingegeben werden muss. Dieses wird hier bekanntgegeben:
- Passwort #2: 0cd0f5dd
- Schreiben Sie auf dieser Codebasis eine Klasse CheckingAccount, welches ein GiroKonto mit einem gewissen Überziehungskredit (Giro) repräsentiert und sich von Account als Basisklasse ableitet.
- Implementieren Sie den Konstruktor, so dass der Giro-Kreditrahmen als Parameter des Konstruktors übergeben wird. Standardmäßig soll der Giro 0 sein. Verwenden Sie den Konstruktor der Basisklasse.
- Ãœberschreiben Sie die folgende Zugriffsmethode:
- withdraw() → hebt einen Betrag vom Konto ab (nur wenn genug Guthaben in Bezug auf den Giro-Kreditrahmen vorhanden ist, in diesem Fall soll außerdem der Wahrheitswert true zurückgegeben werden)
- Testen Sie Ihre Klasse mit einem Giro von 0 bzw. 100 EUR, indem Sie 5x 100 EUR einzahlen und 5x 150 EUR abheben und danach den Kontostand ausgeben. Der Kontostand muss danach 50 bzw. −100 EUR betragen.
- Geben Sie den Kontostand für 100 EUR Giro in main() zurück.
- Notieren Sie das Ergebnis im Gesamtprotokoll. Dazu fügen Sie einen Screenshot des Programmablaufs auf der Kommandozeile ein. Beantworten Sie ebenfalls die Fragen der Lernzielkontrolle stichwortartig im Protokoll.
Lernzielkontrolle:
- Welche Möglichkeiten zur Wiederverwendung von Code hat man in C++ ?
- Welche Möglichkeiten hat man in anderen Ihnen bekannten Programmiersprachen?
- Erklären Sie stichpunktartig die folgenden Fachbegriffe aus obiger Themenliste:
- 1.1 1.2 1.4 2.1 2.2
Tag #3
Themen #3:
- STL (Standard Template Library)
- std::vector und std::map
- Iteratoren und Aufzählung
- Iteratoren vs. Pointer
- auto-Variablen
- infix vs. prefix Notation
- Operator Overloading
- operator <<
- std::string
- Aggregierung
- is vs. has
- Ableiten vs. Aggregieren (am Beispiel 3D Game)
- Aggregieren mit der STL
- Abstrakte Klassen
- Abstrakte Klassen und Klassenhierarchien
- Zeiger auf abstrakte Basisklassen und Aufrufsemantik
- Interfaces
- OO-Motto: Don’t Ask - Tell!
Videos #3
werden hier hochgeladen
Teil | Video | Thema |
---|---|---|
3.1 | YT | STL Template Library |
3.2 | YT | Aggregieren & Interfaces |
3.3 | YT | Anfang der Ãœbung #3 |
Ãœbung #3
- Die heruntergeladene ZIP-Datei exc3.zip wird entpackt, wobei ein Passwort eingegeben werden muss. Dieses wird hier bekanntgegeben:
- Passwort #3: 2a0c6ea0
- Schreiben Sie auf dieser Codebasis eine Klasse, die eine Bank repräsentiert.
- D.h. die Bank soll mehrere Konten verwalten und Überweisungen erlauben können.
- Dazu implementieren Sie das Interface Bank aus “bank.h” durch Ableiten und Spezialisieren!
- Die Konten sollen durch std::map aggregiert werden (key-value pairs).
- Der map-Schlüssel (key) ist die Kontonummer.
- Jedes map-Element (value) soll ein passwortgeschütztes Konto sein. Dies wird durch die Klasse ProtectedAccount realisiert, welche ein Konto als Referenz und ein Passwort als std::string aggregiert.
- Implementieren Sie nun die folgenden abstrakten Methoden des Interfaces “bank.h” in “cccbank.h”:
// open account // * with account number "account", // * password "password" // * and a reference "a" to a new account // * returns true if the account could be opened successfully virtual bool open_account(int account, std::string passwd, Account *a) = 0; // deposit amount on account // * if account is existing virtual void deposit(int account, float amount) = 0; // withdraw amount from account // * if account is existing // * and if passwd matches the account password // * returns true if the withdrawal was successful virtual bool withdraw(int account, std::string passwd, float amount) = 0; // transfer amount from one account to another one // * if both accounts are existing // * and if passwd matches the account password // * and if the withdrawal was successful // * returns true if the transfer was successful virtual bool transfer(int from, int to, std::string passwd, float amount) = 0; // return the account balance // * if account is existing // * and if passwd matches the account password virtual float balance(int account, std::string passwd) = 0; // return the total bank balance // * which is the sum of all account balances float total_balance();
- Wenn das Interface korrekt implementiert wurde, gibt das Programm eine runde Bilanzsumme aus.
- Noch ein Tipp: Beispiele zu std::map gibt es hier. Die Referenz-Dokumentation der Container-Klasse std::map gibt es hier.
- Fügen Sie bitte den letzten Stand des Quelltextes von cccbank.h im Protokoll ein. Wenn der Code noch nicht komplett funktioniert, ist das nicht weiter tragisch. Die Hauptsache ist, dass Sie das Grundprinzip der Benutzung von Interfaces und Container-Klassen verstanden haben. Beantworten Sie ebenfalls die Fragen der Lernzielkontrolle im Protokoll.
Lernzielkontrolle:
- Was ist eine Container-Klasse?
- Was ist der Unterschied zwischen Aggregieren und Ableiten?
- Was ist der Hauptvorteil von einem Interface?
- Erklären Sie die folgenden Fachbegriffe aus obiger Themenliste:
- 1.1 2.2 2.3 2.4 2.5 3.1 3.2
Tag #4
Themen #4:
- Qt
- UI & Widgets
- Design Patterns → Observer Pattern
- UI Event Loop
- Qt Class Hierarchy
- QWidget State, Properties and Feats
- Widget Specialization
- QObject und QWidget
- paintEvent(), resizeEvent() and mousePressEvent()
- [Signals and Slots]
- [QThreads and Signals]
- Graphische Darstellung
- Text- und Liniengraphik
- QPainter
- Coordinate Systems and Transformations
- Turtle Graphics
- Images as Objects
- Fraktale
- Sierpinsky Fraktal
- Julia-Menge
- Alle Punkte $z$ der komplexen Zahlenfolge $z := z^2 + c$
- Mandelbrot-Menge
- Alle Punkte $c$ mit $z := z^2 + c$ und $|z| < 2$ für alle $z$
Videos #4
werden hier hochgeladen
Teil | Video | Thema |
---|---|---|
4.1 | YT | UI Grundprinzipien & Qt |
4.2 | YT | Graphik mit Qt |
4.3 | YT | Anfang der Ãœbung #4 |
Ãœbung #4
- Die heruntergeladene ZIP-Datei exc4.zip wird entpackt, wobei ein Passwort eingegeben werden muss. Dieses wird hier bekanntgegeben:
- Passwort #4: 2681b340
- Zeichnen Sie auf dieser Codebasis das Mandelbrot-Fraktal, indem Sie die paintEvent()-Methode von QWidget durch Ableiten überschreiben. QWidget ist Bestandteil des Qt Frameworks.
- Modifizieren Sie nur das Modul “painterwidget.cpp/.h”!
- Arithmetik für komplexe Zahlen ist bereits im Header “Complex” definiert.
- Zum Zeichnen verwenden Sie QPainter.
- Mandelbrot Pseudo-Code für eine Iteration für jeweils variables $c$:
int fractal(Complex c, int max_count = 100) { int count = 0; Complex z; while (z.norm() < 4) { z = z*z + c; if (count++ > max_count) return(0); } return(count); }
- D.h. für die Mandelbrot Menge variiert man $c$ für feste Startwerte $z_0 = (0,0)$
- Für die Julia-Menge ist $c$ konstant und man variiert den Startwert $z_0$.
- Optional: Wie würde man das Apfelmännchen farbig darstellen? Tipp: count ≙ Farbe
- Fügen Sie einen Screenshot des Fraktals im Gesamtprotokoll ein (siehe z.B. rechts). Beantworten Sie ebenfalls die Fragen der Lernzielkontrolle im Protokoll.
Lernzielkontrolle:
- Erklären Sie die folgenden Fachbegriffe aus obiger Themenliste:
- 1.1 1.5 1.6 2.2 2.3 2.4
- Erklären Sie die folgenden Fachbegriffe aus obiger Themenliste:
Finale
Wenn Sie nun das vollständige Gesamtprotokoll hochladen, haben Sie den Kurs bestanden. Glückwunsch!
Und was kommt nach C++?
Die hier vorgestellten und vertieften Prinzipien finden sich in allen objekt-orientierten Programmiersprachen wieder und sind damit universelle Programmierprinzipien.
Ansonsten ist nur noch anzumerken:
Wer C++ kann, hat nichts zu befürchten - außer C++23!
Happy C++oding!
PS: Prüfungsvorbereitung
- Schreiben Sie testweise die Probeklausur!
- Der Termin für die Frage- und Antwortstunde gegen Ende des Semesters wird noch bekanntgegeben!