TU-Programmieren_2/lab3/main.ipynb
2025-04-09 10:22:44 +02:00

113 lines
5.3 KiB
Plaintext

{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## A. Klassen mit mehrere Konstruktoren\n",
"\n",
"**Aufgabe:**\n",
"\n",
"- Implementieren Sie in eine Klasse `Vector` mit folgenden Eigenschaften (Details siehe [taskA.Vector.hpp](taskA.Vector.hpp)):\n",
" - Eine private Membervariable vom Typ `std::vector<double>`\n",
" - Drei Konstruktoren\n",
" - Eine `const` Memberfunktion `print()`.\n",
"- Nach der Implementierung von `Vector`: Aktivieren Sie in [taskA.cpp](taskA.cpp) alle gekennzeichneten Stellen (die jetzt kompilieren sollten).\n",
"\n",
"**Demonstration:** Kompilieren Sie Ihr Programm, führen Sie es aus, und erklären Sie in eigenen Worten den Vorteil mehrerer Konstruktoren."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## B. Abgeleitete Klassen und dynamische Speicherverwaltung (*new/delete*)\n",
"\n",
"**Aufgabe:**\n",
"\n",
"- Gegeben ist eine abstrakte Schnittstellenklasse `Device` ([taskB.Device.hpp](taskB.Device.hpp))\n",
"- Ebenso gegeben sind folgende Klassen, die die Schnittstelle `Device` implementieren: \n",
" - `WashingMachine` ([taskB.WashingMachine.hpp](taskB.WashingMachine.hpp)) \n",
" - `Train` ([taskB.Train.hpp](taskB.Train.hpp))\n",
" \n",
"- Implementieren Sie eine weitere Klasse `Car` ([taskB.Car.hpp](taskB.Car.hpp)) die ebenfalls die Schnittstelle `Device` implementiert\n",
"- Erweitern Sie die `main`-Funktion in [taskB.cpp](taskB.cpp):\n",
" - Allozieren Sie mit `new` dynamische Instanzen Ihrer Klasse und fügen Sie die Zeiger auf diese Instanzen zum bereits vorhandenen Vektor hinzu.\n",
" - Deallozieren Sie am Ende alle dynamische allozieren Instanzen mit `delete`\n",
"- Speicherlecks:\n",
" - Überprüfen Sie ob Ihr Programmdurchlauf Speicherlecks aufweist, indem Sie mit `-fsanitize=address` kompilieren und das Programm ausführen.\n",
" - Sie können ein Speicherleck provozieren, indem Sie kein `delete` verwenden (also keine Deallokation durchführen).\n",
"\n",
"**Demonstration:** \n",
"- Erklären Sie in eigenen Worten, welchen Vorteil eine Schnittstellenklasse als Basisklasse bietet; welche Einschränkungen hatten Sie z.B. bei der Wahl der Membervariblen für Ihre Klasse `Car`?\n",
"- Kompilieren Sie Ihr Programm mit der Compiler-Option `-fsanitize=address` und führen Sie Ihr Programm aus; provozieren Sie ein Speicherleck und erklären Sie in eigenen Worten das Problem.\n",
"\n",
"**Wichtiger allgemeiner Hinweis:** Explizite dynamische Speicherverwaltung (`new`/`delete`) sollte **immer nur gekapselt** mit **klarer Regelung des Besitzes** der dynamischen Ressourcen erfolgen: also nur innerhalb einer Klasse/Datenstruktur."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"**CMake:** Sie können (sofern Ihr Compiler dies unterstützt) die oben erwähnte Option auch an CMake übergeben:\n",
"\n",
"```shell\n",
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug -D CMAKE_CXX_FLAGS=\"-fsanitize=address\"\n",
"cmake --build build --target taskC\n",
"./build/taskC\n",
"```"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## C. Generische Funktion/Klassen (*templates*)\n",
"\n",
"In der Datei [taskC.one.hpp](taskC.one.hpp) sind im Namensraum `one` zwei Sätze von Funktionsüberladungen `add` und `sum` gegeben.\n",
"\n",
"**Aufgabe 1:**\n",
"\n",
"- Implementieren Sie in [taskC.two.hpp](taskC.two.hpp) im Namensraum `two` zwei Funktions-Templates `add` und `sum`, die Anstelle von `one::add` und `one::sum` verwendet werden können\n",
"- Nach der Implementierung: stellen Sie in [taskC.cpp](taskC.cpp) den verwendeten Namensraum von `one` auf `two` um, und überprüfen Sie die Funktionalität (die sich nicht geändert haben sollte).\n",
"\n",
"**Demonstration 1:** Kompilieren Sie Ihr Programm und führen Sie es aus. Könnten Sie mittels Ihrer zwei Funktions-Templates nun (neben `int` und `double`) beliebige andere Typen addieren und summieren? Welche Voraussetzungen gelten für die Template-Typen bei Ihren Funktionen?\n",
"\n",
"**Aufgabe 2:**\n",
"\n",
"- Kopieren Sie die Datei [taskA.Vector.hpp](taskA.Vector.hpp) als [taskA.VectorT.hpp](taskA.VectorT.hpp):\n",
" - Benennen Sie die Klasse in `VectorT` um\n",
" - **Entfernen Sie den dritten Konstruktor** (den mit dem `std::function<double()>` Parameter), da eine Umsetzung erweiterte C++-Kenntnisse erfordern wuerde. \n",
" - Verwandeln Sie die Klasse in ein Klassen-Template, indem Sie den im Vektor abgespeicherten Typ als Template-Typ verwenden:\n",
" ```cpp\n",
" template <typename T>\n",
" struct VectorT {\n",
" private:\n",
" std::vector<T> data;\n",
" ...\n",
" };\n",
" ```\n",
"\n",
"**Demonstration 2:** Erklären Sie, wie Sie bei der Umwandlung für von `Vector` zu `VectorT` vorgegangen sind."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.12.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}