Menu
CoddyTech

Opaque Structs definieren

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

Da du jetzt das Konzept opaker Zeiger verstehst, sehen wir uns an, wie du das Muster vervollständigst. Der Header deklariert, dass ein Typ existiert, aber in der Quelldatei definierst du, was tatsächlich darin enthalten ist.

Hier ist der vollständige Aufbau. 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 nicht sichtbar!
    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 { ... } kommt nur in der Datei .c vor. Jede Datei, die counter.h einbindet, weiß, dass Counter existiert, kann aber weder value noch step sehen. Der Versuch, c->value in main.c zu schreiben, würde einen Compilerfehler verursachen: Die Member sind tatsächlich unsichtbar.

Diese Trennung ist 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 veranschaulicht. Du übst, die Definition der Struktur in der Quelldatei zu verbergen, sodass ihre internen Elemente für jeden Code, der dein Modul verwendet, vollständig unsichtbar sind.

Du erstellst drei Dateien:

  • timer.h: Dies ist deine öffentliche Schnittstelle. Deklariere einen opaken Typ Timer ausschließlich mit einer Vorwärtsdeklaration: Hier darf es keinen Strukturkörper geben! 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 ihn auf). Verwende Include-Guards mit dem Symbol TIMER_H.
  • timer.c: Hier liegt das Geheimnis. Definiere die eigentliche struct Timer mit zwei verborgenen Elementen: int seconds und int running (verwende 1 für laufend und 0 für angehalten). Implementiere deinen Konstruktor so, dass er Speicher für die Struktur reserviert, seconds mit dem übergebenen 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 zu bestätigen, dass er erfolgreich erstellt wurde. Da die Strukturelemente verborgen sind, kannst du nicht direkt darauf zugreifen. Genau darum geht es! Gib einfach eine Meldung aus, die die Erstellung bestätigt, gib dann den Timer frei und gib eine Meldung zur Bereinigung 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 übergebenen Sekundenwert. Gib eine Meldung zur Erstellung aus, gib dann 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, da der Strukturkörper nur in timer.c definiert ist. Das ist echte Kapselung: Die Implementierungsdetails sind für Nutzer 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: Gib "Timer created" aus
    
    // 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