Menu
Coddy logo textTech

Opaque Structs definieren

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

Nachdem du das Konzept der undurchsichtigen Zeiger verstanden hast, sehen wir uns nun an, wie man das Muster vervollständigt. Der Header deklariert, dass ein Typ existiert, aber in der Quelldatei definierst du, was tatsächlich darin enthalten ist.

Hier ist die vollständige Einrichtung. Zuerst der Header mit nur der Vorwärtsdeklaration:

// counter.h
#ifndef COUNTER_H
#define COUNTER_H

typedef struct Counter Counter;  // Unvollständiger Typ

Counter *create_counter(int start);
void free_counter(Counter *c);

#endif

Dann enthält die Quelldatei die eigentliche Struct-Definition:

// counter.c
#include "counter.h"
#include <stdlib.h>

struct Counter {
    int value;      // Von außen verborgen!
    int step;
};

Counter *create_counter(int start) {
    Counter *c = malloc(sizeof(Counter));
    c->value = start;
    c->step = 1;
    return c;
}

void free_counter(Counter *c) {
    free(c);
}

Der entscheidende Punkt: struct Counter { ... } erscheint nur in der .c-Datei. Jede Datei, die counter.h einbindet, weiß, dass Counter existiert, kann aber value oder step nicht sehen. Der Versuch, c->value in main.c zu schreiben, würde einen Compilerfehler verursachen: Die Member sind tatsächlich unsichtbar.

Diese Trennung bildet die Grundlage der Kapselung in C. Der nächste Schritt besteht darin, kontrollierten Zugriff über Getter- und Setter-Funktionen bereitzustellen.

challenge icon

Aufgabe

Einfach

Lass uns ein Timer-Modul erstellen, das das Muster des opaken Zeigers demonstriert. Du übst, die Strukturdefinition innerhalb der Quelldatei zu verbergen, sodass ihre internen Member für jeglichen Code, der dein Modul verwendet, vollständig unsichtbar sind.

Du wirst drei Dateien erstellen:

  • timer.h: Dies ist deine öffentliche Schnittstelle. Deklariere einen opaken Typ Timer, indem du nur eine Vorwärtsdeklaration verwendest: Hier darf kein Struct-Körper stehen! Deklariere außerdem zwei Funktionen: create_timer (nimmt eine Ganzzahl für die Sekunden entgegen und gibt einen Timer-Zeiger zurück) und free_timer (nimmt einen Timer-Zeiger entgegen und räumt auf). Verwende Include-Guards mit dem Symbol TIMER_H.
  • timer.c: Hier befindet sich das Geheimnis. Definiere die tatsächliche struct Timer mit zwei verborgenen Membern: int seconds und int running (verwende 1 für laufend und 0 für angehalten). Implementiere deinen Konstruktor so, dass er die Struktur allokiert, seconds mit dem bereitgestellten Wert initialisiert und running auf 1 setzt. Implementiere den Destruktor, um den Speicher freizugeben.
  • main.c: Verwende dein Timer-Modul, um einen Timer zu erstellen, und bestätige, dass er erfolgreich erstellt wurde. Da die Struct-Member verborgen sind, kannst du nicht direkt auf sie zugreifen. Genau darum geht es! Gib einfach eine Meldung aus, die die Erstellung bestätigt, gib anschließend den Timer frei und gib eine Aufräummeldung aus.

Du erhältst eine Eingabe: die Anzahl der Sekunden (eine Ganzzahl), mit der der Timer initialisiert werden soll.

Erstelle in deiner Hauptdatei einen Timer mit dem bereitgestellten Sekundenwert. Gib eine Erstellungsmeldung aus, gib anschließend den Timer frei und gib eine Bestätigung aus.

Gib die Ausgabe in diesem Format aus:

Timer created
Timer freed

Die entscheidende Erkenntnis ist, dass main.c mit Timer-Zeigern arbeiten kann, aber keine Möglichkeit hat, direkt auf seconds oder running zuzugreifen. Der Versuch, t->seconds in main.c zu schreiben, würde einen Compilerfehler verursachen, weil der Struct-Körper nur in timer.c definiert ist. Das ist echte Kapselung: Die Implementierungsdetails sind für die Benutzer deines Moduls vollständig verborgen.

Probier es selbst

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

int main() {
    int seconds;
    scanf("%d", &seconds);
    
    // TODO: Erstelle einen Timer mit dem angegebenen Sekundenwert
    
    // TODO: Print "Timer created"
    
    // TODO: Gib den Timer frei
    
    // TODO: Gib "Timer 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