Objektorientierte Programmierung (OOP)
Lerne Kapselung, Vererbung und Laufzeitpolymorphie in C++ im Vergleich zu C.
Was ist objektorientierte Programmierung in C++?
OOP strukturiert Programme um Objekte mit Zustand, Invarianten und Verhalten. C++ unterstützt dies mit Klassen, Zugriffsschutz, Vererbung und virtuellem Dispatch; C setzt die Mechanismen explizit um.
Die vier OOP-Grundprinzipien
- Kapselung schützt Invarianten durch kontrollierten Zugriff.
- Abstraktion lässt Aufrufer von einer kleinen öffentlichen Schnittstelle abhängen.
- Vererbung spezialisiert einen gültigen Basisklassenvertrag.
- Polymorphie wählt über virtuelle Aufrufe das Verhalten des konkreten Objekts.
Umsetzung in C und C++
C kombiniert ein Struct mit Funktionszeigern; Konventionen und API-Funktionen sichern Invarianten und Besitz.
C++ verwendet privaten Zustand, Vererbung und override; der Compiler prüft Zugriff und Signaturen.
Codebeispiele in C und C++
#include <stdio.h>
typedef struct Account Account;
typedef void (*MonthEnd)(Account *account);
struct Account {
const char *owner;
double balance;
double interest_rate;
MonthEnd month_end;
};
void standard_month_end(Account *account) {
(void)account;
}
void savings_month_end(Account *account) {
account->balance *= 1.0 + account->interest_rate;
}
void print_account(Account *account) {
account->month_end(account);
printf("%s: %.2f\n", account->owner, account->balance);
}
int main(void) {
Account accounts[] = {
{"Ada", 150.0, 0.0, standard_month_end},
{"Lin", 200.0, 0.05, savings_month_end}
};
for (int i = 0; i < 2; ++i) {
print_account(&accounts[i]);
}
return 0;
}
Ada: 150.00
Lin: 210.00
#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
class Account {
std::string owner_;
double balance_;
protected:
void add_balance(double amount) { balance_ += amount; }
public:
Account(std::string owner, double balance)
: owner_(std::move(owner)), balance_(balance) {}
virtual ~Account() = default;
virtual void month_end() {}
const std::string& owner() const { return owner_; }
double balance() const { return balance_; }
};
class SavingsAccount final : public Account {
double interest_rate_;
public:
SavingsAccount(std::string owner, double balance, double rate)
: Account(std::move(owner), balance), interest_rate_(rate) {}
void month_end() override {
add_balance(balance() * interest_rate_);
}
};
int main() {
Account standard("Ada", 150.0);
SavingsAccount savings("Lin", 200.0, 0.05);
std::vector<Account *> accounts{&standard, &savings};
std::cout << std::fixed << std::setprecision(2);
for (Account *account : accounts) {
account->month_end();
std::cout << account->owner() << ": "
<< account->balance() << '\n';
}
}
Ada: 150.00
Lin: 210.00
C und C++ im Vergleich
C speichert Zustand und Funktionszeiger in einem Struct. C++ hält den Kontostand privat, erbt eine Schnittstelle und überschreibt eine virtuelle Methode. Beide Varianten vermeiden Typprüfungen im aufrufenden Code.
C verwendet Namenskonventionen, Callbacks, Makros und structs mit Kontext.
C++ bietet Abstraktionen mit klarem Gültigkeitsbereich, die typsicher sind und zur Laufzeit meist nichts zusätzlich kosten.
Übungen zur Vertiefung
Führe beide Versionen aus und ändere dann den Code, um zu beobachten, welche Sicherheit jede Sprache bietet.
- Schreibe den Mechanismus zuerst in C und verwende erst dann die entsprechende C++-Funktion.
- Ersetze das manuelle Freigeben von Ressourcen durch RAII.
- Prüfe, ob die Funktion Speicherreservierungen oder Aufrufe virtueller Funktionen verursacht.
Mit einer Challenge üben
Nutze den Inhalt dieser Lektion, um ein echtes Problem zu lösen. Jede Challenge läuft im Browser, mit sofortigen Tests und einem KI-Review.
Alle Challenges