Wird geladen...

Kapselung und Zugriffsmodifizierer in C++ (public, protected, private)

Lernen Sie Kapselung und Zugriffsmodifizierer in C++, um sichere und gut strukturierte Klassen zu entwickeln.

Encapsulation (Kapselung) ist eines der vier grundlegenden Konzepte der objektorientierten Programmierung (OOP). Es bedeutet, dass die Daten (Eigenschaften) einer Klasse vor der Außenwelt verborgen werden und nur über definierte Methoden zugänglich sind. Dieser Ansatz bewahrt die Datenintegrität und macht die interne Struktur einer Klasse unabhängig von der externen Nutzung.


1) Was ist Encapsulation?

Encapsulation ist das Prinzip der „Datenverbergung“. Die internen Details einer Klasse (Eigenschaften, Hilfsmethoden) sind von außen nicht sichtbar. Der Benutzer interagiert nur über die öffentliche Schnittstelle der Klasse.

Vorteile der Kapselung:


2) Zugriffsmodifizierer

In C++ gibt es drei Zugriffsmodifizierer:

Modifizierer Zugriffsebene Verwendung
public Überall zugänglich Öffentliche Schnittstelle (API) der Klasse
protected Nur innerhalb der Klasse und abgeleiteten Klassen zugänglich Gemeinsame Funktionalität für Vererbung
private Nur innerhalb der Klasse zugänglich Datenfelder, Hilfsfunktionen

3) Beispiel zur Kapselung mit der Klasse Book

Im Folgenden ein Beispiel für eine Book-Klasse, die das Prinzip der Kapselung demonstriert.


#include <iostream>
#include <string>
using namespace std;

class Book {
private:
    string title;
    string author;
    double price;
    int pageCount;

public:
    // Konstruktor
    Book(string t, string a, double p, int pc)
        : title(t), author(a), price(p), pageCount(pc) {}

    // Getter und Setter
    string GetTitle() const { return title; }
    string GetAuthor() const { return author; }

    double GetPrice() const { return price; }
    void SetPrice(double p) {
        if (p >= 0) price = p;
        else cout << "Der Preis darf nicht negativ sein!" << endl;
    }

    int GetPageCount() const { return pageCount; }

    void Print() const {
        cout << "Buch: " << title
             << " | Autor: " << author
             << " | Seiten: " << pageCount
             << " | Preis: " << price << " €" << endl;
    }
};

int main() {
    Book b("C++ Primer", "Lippman", 180.0, 950);

    b.Print();
    b.SetPrice(-50); // Ungültig
    b.SetPrice(210);
    b.Print();
}

Private Felder können nicht direkt verändert werden. Änderungen dürfen nur über kontrollierte Methoden wie SetPrice() erfolgen.


4) Geschützte (protected) Felder und Vererbung

Abgeleitete Klassen können direkt auf protected-Felder zugreifen. Dies ermöglicht es der Unterklasse, die Daten der Basisklasse zu erweitern oder wiederzuverwenden.


class EBook : public Book {
protected:
    string format; // z. B.: PDF, EPUB

public:
    EBook(string t, string a, double p, int pc, string f)
        : Book(t, a, p, pc), format(f) {}

    void PrintWithFormat() const {
        cout << GetTitle() << " (" << format << ")" << endl;
    }
};

Die abgeleitete Klasse fügt hier ein neues Merkmal (format) hinzu, ohne die Kapselung zu verletzen.


5) Das friend-Schlüsselwort

Normalerweise können auf private-Mitglieder nur innerhalb der Klasse zugegriffen werden. Es kann jedoch vorkommen, dass eine andere Klasse oder Funktion auf diese privaten Daten zugreifen muss. In diesem Fall kann eine friend-Deklaration verwendet werden.


class Book {
private:
    string title;
    double price;
public:
    Book(string t, double p) : title(t), price(p) {}

    // friend-Funktionsdeklaration
    friend void ApplyDiscount(Book& b, double rate);
};

void ApplyDiscount(Book& b, double rate) {
    b.price *= (1 - rate); // Zugriff auf private Variable
}

int main() {
    Book b("Design Patterns", 300);
    ApplyDiscount(b, 0.1);
}

Die Verwendung von friend sollte mit Vorsicht erfolgen, da sie die Kapselung verletzt. Sie sollte nur in Ausnahmefällen verwendet werden (z. B. bei Operatorüberladung oder Debugging-Werkzeugen).


6) Gestaltungsprinzipien für Getter und Setter


class Book {
private:
    string title;
    double price;
public:
    Book(string t, double p) : title(t), price(p) {}

    string GetTitle() const { return title; } // Nur lesen
    void ApplyDiscount(double rate) { price *= (1 - rate); } // Verhalten statt Setter
};

7) Datensicherheit mit dem const-Schlüsselwort

const-Methoden verändern den Zustand der Klasse nicht. Dies unterstützt die Kapselung und verhindert unbeabsichtigte Änderungen.


class SafeBook {
private:
    string title;
public:
    SafeBook(string t) : title(t) {}

    string GetTitle() const { return title; } // const-Methode
    void SetTitle(string t) { title = t; }
};

Wenn eine Get-Methode ohne const deklariert wird, verletzt sie dieses Prinzip und kann zu unerwarteten Fehlern führen.


8) Unveränderliches (Immutable) Objektmuster

Gemäß dem Kapselungsprinzip können einige Objekte als „unveränderlich“ (immutable) entworfen werden. Alle ihre Mitglieder sind const und es gibt keine Setter-Methoden.


class ImmutableBook {
private:
    const string title;
    const string author;
    const int pages;
public:
    ImmutableBook(string t, string a, int p)
        : title(t), author(a), pages(p) {}

    string GetTitle() const { return title; }
    string GetAuthor() const { return author; }
    int GetPages() const { return pages; }
};

Dieser Ansatz gewährleistet Datenintegrität, insbesondere in Multi-Threading-Umgebungen.


9) Kapselung und Zustandsverwaltung von Objekten

Kapselung steuert nicht nur den Zugriff, sondern stellt auch sicher, dass ein Objekt in einem gültigen Zustand bleibt. Der interne Zustand der Klasse sollte stets gültige Werte haben.


class ValidatedBook {
private:
    double price;
public:
    void SetPrice(double p) {
        if (p < 0) throw invalid_argument("Der Preis darf nicht negativ sein.");
        price = p;
    }
};

Solche Validierungsmechanismen garantieren, dass die Klasse einen „gültigen Zustand“ beibehält und verhindern ungültige Eingaben von außen.


10) TL;DR

  • Kapselung bedeutet, Daten zu verbergen und über Verhalten kontrolliert darauf zuzugreifen.
  • private: nur innerhalb der Klasse zugänglich.
  • protected: innerhalb der Klasse und abgeleiteten Klassen zugänglich.
  • public: überall zugänglich (Klassen-API).
  • friend erlaubt externen Zugriff auf private Daten (vorsichtig verwenden).
  • Validierung und die Verwendung von const in Gettern/Settern sind entscheidend.
  • Unveränderliche Objekte erhöhen die Datensicherheit.
  • Kapselung ist ein zentrales Prinzip für wartbare und fehlerfreie Software.
  • Alle Beispiele sind mit Visual Studio 2022 und GCC 11+ kompatibel.

Ähnliche Artikel