C++ OOP & Klassen

6 Kernkonzepte
Die wichtigsten Konzepte der objektorientierten Programmierung in C++: class · Konstruktor · Destruktor · Zugriffsmodifikatoren · Memberfunktionen · this Objektorientierte Programmierung (OOP) in C++ ermöglicht die Modellierung von realen Objekten durch Klassen. Diese Konzepte sind essenziell für die Entwicklung komplexer, wartbarer Anwendungen.

Klassen – Blaupausen für Objekte

class · struct · Objekt
// Klassendefinition class Person { public: std::string name; int age; void greet() { std::cout << "Hallo!"; } }; // Objekt erzeugen Person p; p.name = "Anna"; p.greet();

Klassen sind die zentrale Einheit der objektorientierten Programmierung in C++. Sie definieren Daten (Membervariablen) und Funktionen (Memberfunktionen), die das Verhalten von Objekten beschreiben.

Class vs. Struct

Konzept class struct
Standard-Zugriff private public
Verwendung Komplexe Objekte mit Kapselung Einfache Datencontainer
Vererbung private standardmäßig public standardmäßig
Beispiele
// Klasse mit Daten und Funktionen
class Auto {
public:
std::string marke;
int baujahr;
void fahren() {
std::cout << marke << " fährt..." << std::endl;
}
};
// Objekt auf dem Stack
Auto meinAuto;
meinAuto.marke = "Tesla";
meinAuto.baujahr = 2023;
meinAuto.fahren();
// Objekt auf dem Heap (dynamisch)
Auto* pAuto = new Auto();
pAuto->marke = "BMW";
pAuto->fahren();
delete pAuto;
Tipp: Verwenden Sie struct für einfache Datencontainer ohne Methoden (wie in C). Verwenden Sie class für komplexe Objekte mit Kapselung und Methoden.

Konstruktor – Objekte initialisieren

ClassName() · : Initliste · Überladung
// Konstruktor mit Initialisierungsliste class Person { public: Person(std::string n, int a) : name(n), age(a) {} private: std::string name; int age; };

Konstruktoren werden automatisch aufgerufen, wenn ein Objekt erstellt wird. Sie initialisieren Membervariablen und führen notwendige Setups durch.

Konstruktor-Typen

Typ Beschreibung Beispiel
Standardkonstruktor Keine Parameter Person() {}
Parametrisierter Konstruktor Mit Parametern Person(string n, int a)
Kopierkonstruktor Objekt kopieren Person(const Person& p)
Move-Konstruktor Ressourcen verschieben Person(Person&& p)
Delegierender Konstruktor Ruft anderen Konstruktor auf Person() : Person("", 0) {}
Beispiele
class Konto {
public:
// Standardkonstruktor
Konto() : kontostand(0.0) {
std::cout << "Konto erstellt" << std::endl;
}
// Parametrisierter Konstruktor
Konto(double start) : kontostand(start) {}
// Kopierkonstruktor
Konto(const Konto& other) : kontostand(other.kontostand) {}
// Delegierender Konstruktor
Konto(int id) : Konto() { this->id = id; }
private:
double kontostand;
int id;
};
// Verwendung
Konto k1; // Standardkonstruktor
Konto k2(1000.0); // Parametrisierter Konstruktor
Konto k3(k2); // Kopierkonstruktor
Tipp: Verwenden Sie die Initialisierungsliste (nach dem :) für Membervariablen – sie ist effizienter als Zuweisungen im Konstruktor-Körper.

Zugriffsmodifikatoren – public, private, protected

public · private · protected
// Klasse mit Zugriffsmodifikatoren class Bankkonto { private: double kontostand; // Nur von innen zugänglich public: void einzahlen(double betrag); // Von außen zugänglich protected: int kontoNummer; // Für Vererbung };

Zugriffsmodifikatoren steuern die Sichtbarkeit von Membern einer Klasse. Sie sind die Grundlage der Kapselung in C++.

Die drei Zugriffsmodifikatoren

Modifikator Zugriff von Beschreibung
public Überall Member sind von überall zugänglich (Schnittstelle)
private Nur innerhalb der Klasse Member sind nur von der Klasse selbst zugänglich (Kapselung)
protected Innerhalb der Klasse und abgeleiteten Klassen Member sind für Vererbung zugänglich
Beispiele
class Mitarbeiter {
private:
double gehalt; // Nur innerhalb der Klasse
std::string passwort;
public:
std::string name; // Überall zugänglich
void setGehalt(double g) {
if (g > 0) gehalt = g;
}
double getGehalt() const { return gehalt; }
protected:
int mitarbeiterID; // Für Vererbung
};
// Verwendung
Mitarbeiter m;
m.name = "Anna"; // OK (public)
// m.gehalt = 5000; // Fehler (private)
m.setGehalt(5000); // OK (public)
std::cout << m.getGehalt(); // 5000
Tipp: Machen Sie Membervariablen private und bieten Sie public Getter/Setter an. Das ermöglicht Kontrolle und Validierung beim Zugriff.

Memberfunktionen – Methoden einer Klasse

void methode() · const · inline
// Memberfunktion (Methode) class Rechteck { public: double breite, hoehe; double flaeche() const { return breite * hoehe; } void skaliere(double faktor); // Deklaration }; // Definition außerhalb void Rechteck::skaliere(double faktor) { breite *= faktor; hoehe *= faktor; }

Memberfunktionen (Methoden) definieren das Verhalten eines Objekts. Sie können innerhalb oder außerhalb der Klasse definiert werden und haben Zugriff auf alle Member.

Beispiele
class Timer {
public:
// Konstruktor
Timer() : startzeit(std::chrono::steady_clock::now()) {}
// const-Methode (ändert Objekt nicht)
double verstrichen() const {
auto jetzt = std::chrono::steady_clock::now();
auto dauer = std::chrono::duration_cast<std::chrono::milliseconds>(jetzt - startzeit);
return dauer.count() / 1000.0;
}
// Inline-Methode (Compiler-Optimierung)
void reset() inline {
startzeit = std::chrono::steady_clock::now();
}
private:
std::chrono::steady_clock::time_point startzeit;
};
// Verwendung
Timer t;
// ... etwas tun ...
std::cout << "Zeit: " << t.verstrichen() << "s";
Tipp: Deklarieren Sie Methoden, die das Objekt nicht verändern, als const. Das ermöglicht die Verwendung auf const-Objekten und verbessert die Typsicherheit.

this – Zeiger auf das aktuelle Objekt

this-> · *this · this->
// this-Zeiger verwenden class Person { public: void setName(std::string name) { this->name = name; // this zeigt auf aktuelles Objekt
} Person& setNameChain(std::string name) { this->name = name; return *this; // Rückgabe des Objekts für Method Chaining } private: std::string name; };

this ist ein versteckter Zeiger, der in jeder Memberfunktion auf das aktuelle Objekt zeigt. Er wird verwendet, um Membervariablen zu referenzieren oder das Objekt selbst zurückzugeben.

Beispiele
class Rechnung {
public:
// this für Parameter mit gleichem Namen
void setBetrag(double betrag) {
this->betrag = betrag;
}
// Method Chaining mit this
Rechnung& setBetragChain(double betrag) {
this->betrag = betrag;
return *this;
}
Rechnung& setMwst(double mwst) {
this->mwst = mwst;
return *this;
}
double getBetrag() const { return betrag; }
private:
double betrag = 0.0;
double mwst = 0.19;
};
// Method Chaining
Rechnung r;
r.setBetragChain(100.0).setMwst(0.07);
std::cout << r.getBetrag(); // 100.0
// this in const-Methoden (this ist const)
void print() const {
// this->betrag = 100; // Fehler: this ist const
std::cout << this->betrag;
}
Tipp: Verwenden Sie this-> wenn eine Membervariable und ein Parameter den gleichen Namen haben. Für Method Chaining geben Sie *this zurück.

Destruktor – Ressourcen freigeben

~ClassName() · RAII · virtual
// Destruktor class Ressource { public: Ressource() { std::cout << "Ressource erstellt"; } ~Ressource() { std::cout << "Ressource freigegeben"; } };

Destruktoren werden automatisch aufgerufen, wenn ein Objekt zerstört wird. Sie geben Ressourcen frei (Speicher, Dateien, Verbindungen) und sind essenziell für das RAII-Prinzip.

Beispiele
class DateiHandler {
public:
// Konstruktor öffnet Datei
DateiHandler(const std::string& name) {
datei.open(name);
if (datei.is_open()) {
std::cout << "Datei geöffnet" << std::endl;
}
}
// Destruktor schließt Datei
~DateiHandler() {
if (datei.is_open()) {
datei.close();
std::cout << "Datei geschlossen" << std::endl;
}
}
// Schreibzugriff
void schreibe(const std::string& text) {
if (datei.is_open()) {
datei << text << std::endl;
}
}
private:
std::ofstream datei;
};
// Verwendung (RAII)
int main() {
DateiHandler handler("test.txt");
handler.schreibe("Hallo Welt");
// Destruktor wird automatisch aufgerufen
} // -> "Datei geschlossen"
Tipp: Destruktoren sollten virtual sein, wenn die Klasse als Basisklasse für Vererbung verwendet wird. Das stellt sicher, dass der korrekte Destruktor aufgerufen wird.

C++ OOP & Klassen im Überblick

class Blaupause für Objekte
Daten + Methoden
public Schnittstelle
Von außen zugänglich
private Kapselung
Nur von innen
this Zeiger auf Objekt
Selbstreferenz
RAII Ressourcenverwaltung
Konstruktor/Destruktor
const Unveränderliche Methoden
const-Korrektheit

Quick Summary

class
Klasse definieren
ClassName()
Konstruktor
private
Kapselung
void methode()
Memberfunktion
this
Selbstreferenz
~Class()
Destruktor
class Person { public: Person(string n) : name(n) {} private: string name; }; · ~Person() { /* cleanup */ }