Konstruktor-Muster
Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 12 von 61.
In Sprachen wie Java oder C++ erstellst du Objekte mithilfe von Konstruktoren: speziellen Funktionen, die automatisch Speicher reservieren und Felder initialisieren. C verfügt über keine solche Funktion, aber wir können sie mit einem einfachen Muster simulieren: einer create_-Funktion.
Eine Konstruktorfunktion in C führt typischerweise drei Dinge aus: Sie reserviert Speicher mit malloc, initialisiert alle Felder mit den richtigen Werten und gibt einen Zeiger auf das neue Objekt zurück:
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
Die Funktion gibt einen Zeiger zurück, weil das Objekt auf dem Heap und nicht auf dem Stack lebt. Das bedeutet, dass es nach der Rückkehr der Funktion bestehen bleibt und frei weitergegeben werden kann. Der Aufrufer verwendet es so:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Beachte, wie der Konstruktor alle komplizierten Details handhabt: die Struktur zuzuweisen, Speicherplatz für den String zuzuweisen und die Daten zu kopieren. Der Aufrufer stellt einfach die Anfangswerte bereit und erhält ein sofort verwendbares Objekt. Dadurch wird die Logik zur Erstellung an einer Stelle gekapselt, was deinen Code übersichtlicher und weniger fehleranfällig macht.
Aufgabe
EinfachErstellen wir ein Book-Modul, das das Konstruktormuster verwendet, um Buchobjekte auf dem Heap zu erstellen. Du übst das Schreiben einer create_-Funktion, die die gesamte Speicherzuweisung und Initialisierung übernimmt und einen einsatzbereiten Zeiger zurückgibt.
Du wirst drei Dateien erstellen:
book.h: Deklariere eineBook-Struktur mit zwei Mitgliedern:char *title(ein Zeiger auf eine dynamisch zugewiesene Zeichenkette) undint pages. Deklariere außerdem eine Konstruktorfunktioncreate_book, die eine Titelzeichenkette und eine Seitenanzahl entgegennimmt und anschließend einen Zeiger auf ein neu erstelltes Book zurückgibt. Verwende Include-Guards mit dem SymbolBOOK_H.book.c: Implementiere die Funktioncreate_book. Dein Konstruktor sollte Speicher für die Book-Struktur selbst zuweisen und anschließend separaten Speicher für die Titelzeichenkette reservieren (denke daran, das Nullterminierungszeichen zu berücksichtigen), den Titel in den neuen Speicher kopieren, das Feld pages setzen und den Zeiger auf das neue Book zurückgeben.main.c: Verwende deinen Konstruktor, um ein Buch zu erstellen und seine Informationen anzuzeigen.
Du erhältst zwei Eingaben: den Buchtitel (eine Zeichenkette) und die Anzahl der Seiten (eine Ganzzahl).
Verwende in deiner Hauptdatei create_book, um mit den angegebenen Werten ein neues Buch zu erstellen, und gib anschließend seine Informationen in diesem Format aus:
Title: {title}
Pages: {pages}Bei den Eingaben The C Programming Language und 272 würde die Ausgabe beispielsweise folgendermaßen aussehen:
Title: The C Programming Language
Pages: 272Denke daran, dass dein Konstruktor die gesamte Erstellungslogik kapselt: Der Aufrufer stellt einfach die Anfangswerte bereit und erhält ein vollständig initialisiertes, sofort verwendbares Objekt.
Probier es selbst
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Eingabe lesen
fgets(title, sizeof(title), stdin);
// Zeilenumbruch entfernen, falls vorhanden
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO: Verwende create_book, um ein neues Buch mit den angegebenen Werten zu erstellen
// TODO: Gib die Buchinformationen im erforderlichen Format aus:
// Title: {title}
// Pages: {pages}
// TODO: Vergiss nicht, den allokierten Speicher freizugeben, wenn fertig
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-ImplementierungRechteck-ImplementierungPolymorphe VerwendungShape-ContainerÜbe selbstständig: Online-C-Compiler