Menu
CoddyTech

Validierung in Settern

Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 20 von 61.

In der vorherigen Lektion haben wir einfache Setter erstellt, die lediglich Werte zuweisen. Dabei geht jedoch ein entscheidender Vorteil der Kapselung verloren: die Möglichkeit, deine Daten durch das Hinzufügen von Validierungslogik zu schützen.

Betrachten wir einen Counter, der niemals negativ werden soll. Ohne Kapselung könnte jeder c->value = -50 schreiben und den Zustand beschädigen. Mit einem Setter kontrollierst du, welche Werte zulässig sind:

// counter.c
void counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return;  // Ungültige Eingabe ohne Meldung zurückweisen
    }
    c->value = new_value;
}

Negative Werte werden jetzt einfach ignoriert.

Du kannst dich auch dafür entscheiden, einen Statuscode zurückzugeben, um Erfolg oder Misserfolg anzuzeigen:

int counter_set_value(Counter *c, int new_value) {
    if (new_value < 0) {
        return 0;  // Fehlschlag
    }
    c->value = new_value;
    return 1;  // Erfolg
}

Dieses Muster lässt den Aufrufer wissen, ob der Vorgang erfolgreich war. Die entscheidende Erkenntnis ist, dass Setter nicht nur der Zuweisung dienen: Sie sind Wächter, die Regeln dafür durchsetzen, welchen Zustand dein Objekt haben kann. Das ist die wahre Stärke der Kapselung: Dein Objekt bewahrt seine eigene Integrität, unabhängig davon, was externer Code versucht.

challenge icon

Aufgabe

Einfach

Lass uns ein Temperature-Modul erstellen, das seine Daten mithilfe einer Validierung im Setter schützt. Du erstellst einen Temperatur-Tracker, der nur Werte innerhalb eines gültigen Bereichs akzeptiert: So wird gezeigt, wie Setter als Wächter für den Zustand deines Objekts fungieren.

Du erstellst drei Dateien:

  • temperature.h: Deine öffentliche Schnittstelle mit dem Muster des opaken Zeigers. Deklariere einen Typ Temperature ausschließlich mit einer Vorwärtsdeklaration. Deklariere diese Funktionen:
    • create_temperature: nimmt eine Ganzzahl für die Anfangstemperatur entgegen und gibt einen Temperature-Zeiger zurück
    • free_temperature: gibt den zugewiesenen Speicher frei
    • temp_get_degrees: Getter, der den aktuellen Temperaturwert zurückgibt
    • temp_set_degrees: Setter, der einen int zurückgibt (1 bei Erfolg, 0 bei Fehlschlag)
    Verwende Include-Guards mit dem Symbol TEMPERATURE_H.
  • temperature.c: Definiere das tatsächliche struct Temperature mit einem verborgenen Element int degrees. Implementiere alle Funktionen. Entscheidend ist dein Setter. Er sollte nur Werte zwischen -50 und 150 (einschließlich) akzeptieren. Liegt der Wert außerhalb dieses Bereichs, gib 0 zurück und lasse die Temperatur unverändert. Ist der Wert gültig, aktualisiere ihn und gib 1 zurück.
  • main.c: Veranschauliche die Validierung, indem du versuchst, sowohl gültige als auch ungültige Temperaturen zu setzen, und zeige, dass ungültige Werte abgelehnt und gültige akzeptiert werden.

Du erhältst drei Eingaben: die Anfangstemperatur, eine zu setzende gültige Temperatur (innerhalb des Bereichs) und eine zu versuchende ungültige Temperatur (außerhalb des Bereichs).

Erstelle in deiner Hauptdatei ein Temperature mit dem Anfangswert und gib ihn aus. Versuche dann, die ungültige Temperatur zu setzen. Da sie abgelehnt werden sollte, gib das Ergebnis aus und zeige, dass der Wert unverändert bleibt. Setze schließlich die gültige Temperatur, gib das Erfolgsergebnis aus und zeige den aktualisierten Wert. Gib den Speicher frei und bestätige die Bereinigung.

Gib die Ausgabe in diesem Format aus:

Initial: {degrees}
Set {invalid}: {0 or 1}
After invalid: {degrees}
Set {valid}: {0 or 1}
After valid: {degrees}
Freed

Beispielsweise würde die Ausgabe bei den Eingaben 25, 100 und 200 wie folgt aussehen:

Initial: 25
Set 200: 0
After invalid: 25
Set 100: 1
After valid: 100
Freed

Das zeigt die wahre Stärke der Kapselung. Dein Setter setzt die Regeln dafür durch, was als gültige Temperatur gilt, und schützt die Integrität des Objekts unabhängig davon, welche Werte externer Code zuzuweisen versucht.

Probier es selbst

#include <stdio.h>
#include "temperature.h"

int main() {
    // Eingaben einlesen
    int initial, valid_temp, invalid_temp;
    scanf("%d", &initial);
    scanf("%d", &valid_temp);
    scanf("%d", &invalid_temp);
    
    // TODO: Eine Temperature mit dem Anfangswert erstellen
    
    // TODO: Anfangstemperatur ausgeben
    // Format: "Initial: {degrees}"
    
    // TODO: Versuchen, die ungültige Temperatur zu setzen
    // Das Ergebnis ausgeben und zeigen, dass der Wert unverändert bleibt
    // Format: "Set {invalid}: {0 or 1}"
    // Format: "After invalid: {degrees}"
    
    // TODO: Die gültige Temperatur setzen
    // Das Erfolgsergebnis ausgeben und den aktualisierten Wert anzeigen
    // Format: "Set {valid}: {0 or 1}"
    // Format: "After valid: {degrees}"
    
    // TODO: Den Speicher freigeben und "Freed" ausgeben
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C-Compiler