Menu
Coddy logo textTech

Validierung in Settern

Teil des Abschnitts Objektorientierte Programmierung 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 Fehlschlag 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

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 demonstriert, wie Setter als Torwächter für den Zustand deines Objekts fungieren.

Du erstellst drei Dateien:

  • temperature.h: Deine öffentliche Schnittstelle unter Verwendung des Musters für opake Zeiger. 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 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 Misserfolg)
    Verwende Include-Guards mit dem Symbol TEMPERATURE_H.
  • temperature.c: Definiere 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 (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 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 dabei, dass ungültige Werte abgelehnt werden, während gültige Werte 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 main-Datei eine Temperature mit dem Anfangswert und gib sie 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

Dies demonstriert die wahre Stärke der Kapselung. Dein Setter erzwingt die Regeln dafür, was eine gültige Temperatur ausmacht, 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 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 Objektorientierte Programmierung

Übe selbstständig: Online-C-Compiler