Ein mögliches reales Szenario, in dem dies auftreten würde, besteht darin, dass eine Datenbankbibliothek, die in den Tagen geschrieben wurde, als der Festplattenspeicher sehr begrenzt war, ein einzelnes Byte zum Speichern des Felds "Jahr" eines Datums verwendete (z. B. 11. November 1973) hätte 73für das Jahr). Als das Jahr 2000 kam, würde dies jedoch nicht mehr ausreichen, und das Jahr musste dann als kurze (16-Bit) Ganzzahl gespeichert werden. Der relevante (stark vereinfachte) Header für diese Bibliothek könnte folgender sein:
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
Und ein "Client" -Programm wäre:
#include <stdio.h>
#include "dbEntry.h"
int main()
{
int dataBlob = 42;
dbEntry* test = CreateDBE(17, 11, 2019, dataBlob);
//...
int year = GetYear(test);
printf("Year = %d\n", year);
//...
DeleteDBE(test);
return 0;
}
Die "ursprüngliche" Implementierung:
#include <stdlib.h>
#include "dbEntry.h"
struct _dbEntry {
unsigned char d;
unsigned char m;
unsigned char y; // Fails at Y2K!
int dummyData;
};
dbEntry* CreateDBE(int day, int month, int year, int otherData)
{
dbEntry* local = malloc(sizeof(dbEntry));
local->d = (unsigned char)(day);
local->m = (unsigned char)(month);
local->y = (unsigned char)(year % 100);
local->dummyData = otherData;
return local;
}
void DeleteDBE(dbEntry* entry)
{
free(entry);
}
int GetYear(dbEntry* entry)
{
return (int)(entry->y);
}
Beim Ansatz von Y2K würde diese Implementierungsdatei dann wie folgt geändert (alles andere bleibt unberührt):
struct _dbEntry {
unsigned char d;
unsigned char m;
unsigned short y; // Can now differentiate 1969 from 2069
int dummyData;
};
dbEntry* CreateDBE(int day, int month, int year, int otherData)
{
dbEntry* local = malloc(sizeof(dbEntry));
local->d = (unsigned char)(day);
local->m = (unsigned char)(month);
local->y = (unsigned short)(year);
local->dummyData = otherData;
return local;
}
Wenn der Client aktualisiert werden muss, um die neue (Y2K-sichere) Version zu verwenden, sind keine Codeänderungen erforderlich. Möglicherweise müssen Sie nicht einmal neu kompilieren: Eine einfache erneute Verknüpfung mit der aktualisierten Objektbibliothek (sofern dies der Fall ist) kann ausreichen.
structhandelt es sich um eine Black Box mit unbekannten Interna. Wenn der Client die Interna nicht kennt, kann er niemals direkt darauf zugreifen und Sie können sie nach Belieben ändern. Dies ähnelt der Einkapselung in OOP. Die Interna sind privat und Sie ändern das Objekt nur mit öffentlichen Methoden.