Menu
Coddy logo textTech

Validierung in Settern

Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy. Lektion 20 von 61.

In der vorherigen Lektion haben wir grundlegende Setter erstellt, die lediglich Werte zuweisen. Dabei bleibt jedoch ein wesentlicher Vorteil der Kapselung ungenutzt: die Möglichkeit, deine Daten zu schützen, indem Validierungslogik hinzugefügt wird.

Stell dir einen Counter vor, der niemals negativ werden sollte. 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 stillschweigend ablehnen
    }
    c->value = new_value;
}

Jetzt werden negative Werte einfach ignoriert.

Du könntest dich auch dafür entscheiden, einen Statuscode zurückzugeben, um Erfolg oder failure 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 zentrale Erkenntnis ist, dass Setter nicht nur der Zuweisung dienen: Sie sind Wächter, die Regeln darüber durchsetzen, wie der Zustand deines Objekts aussehen darf. Das ist die wahre Stärke der Kapselung: Dein Objekt bewahrt seine eigene Integrität, unabhängig davon, was externer Code zu tun versucht.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Temperature-Modul, das seine Daten mithilfe einer Validierung im Setter schützt. Du erstellst einen Temperatur-Tracker, der nur Werte innerhalb eines gültigen Bereichs akzeptiert – und demonstrierst damit, wie Setter als Wächter für den Zustand deines Objekts fungieren.

Du erstellst drei Dateien:

  • temperature.h: Deine öffentliche Schnittstelle unter Verwendung des undurchsichtigen Zeiger-Musters. Declare einen Typ Temperature nur mit einer Forward declaration. Declare diese Funktionen:
    • create_temperature: nimmt eine Ganzzahl für die initialen Grade entgegen und gibt einen Temperature-Zeiger zurück
    • free_temperature: gibt den reservierten Speicher frei
    • temp_get_degrees: Getter, der den aktuellen Temperaturwert zurückgibt
    • temp_set_degrees: Setter, der ein int zurückgibt (1 für Erfolg, 0 für Failure)
    Verwende Include-Guards mit dem Symbol TEMPERATURE_H.
  • temperature.c: Define die tatsächliche struct Temperature mit einem verborgenen int degrees-member. Implementiere alle Funktionen. Der entscheidende Punkt ist dein Setter. Er sollte nur Werte zwischen -50 und 150 (inclusive) akzeptieren. Wenn der Wert außerhalb dieses Bereichs liegt, gib 0 zurück und lasse die Temperatur unverändert. Wenn der Wert gültig ist, aktualisiere den Wert und gib 1 zurück.
  • main.c: Demonstriere die Validierung, indem du versuchst, sowohl gültige als auch ungültige Temperaturen zu setzen, und zeige, dass ungültige Werte abgelehnt werden, während gültige Werte akzeptiert werden.

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

Erstelle in deiner main-Datei eine Temperature mit dem initialen Wert 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 Erfolgergebnis 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 inputs 25, 100 und 200 wie folgt aussehen:

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

Dies demonstriert die wahre Stärke der Kapselung. Dein Setter setzt die Regeln dafür durch, was eine gültige Temperatur ausmacht, und schützt so 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 lesen
    int initial, valid_temp, invalid_temp;
    scanf("%d", &initial);
    scanf("%d", &valid_temp);
    scanf("%d", &invalid_temp);
    
    // TODO: Erstelle ein Temperature mit dem Anfangswert
    
    // TODO: Gib die Anfangstemperatur aus
    // Format: "Initial: {degrees}"
    
    // TODO: Versuche, die ungültige Temperatur zu setzen
    // Gib das Ergebnis aus und zeige, dass der Wert unverändert bleibt
    // Format: "Set {invalid}: {0 or 1}"
    // Format: "After invalid: {degrees}"
    
    // TODO: Setze die gültige Temperatur
    // Gib das Erfolgsergebnis aus und zeige den aktualisierten Wert
    // Format: "Set {valid}: {0 or 1}"
    // Format: "After valid: {degrees}"
    
    // TODO: Gib den Speicher frei und gib "Freed" aus
    
    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 Object Oriented Programming

Übe selbstständig: Online-C-Compiler