Un possibile scenario del mondo reale in cui ciò potrebbe verificarsi è quando una libreria di database, scritta nei giorni in cui lo spazio su disco rigido era molto limitato, utilizzava un singolo byte per memorizzare il campo "anno" di una data (ad esempio 11-NOV-1973 avrebbe 73per l'anno). Ma, quando è arrivato il 2000, questo non sarebbe più stato sufficiente e l'anno doveva essere archiviato come un intero breve (16 bit). L'intestazione pertinente (molto semplificata) per questa libreria potrebbe essere questa:
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
E un programma "client" sarebbe:
#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;
}
L'implementazione "originale":
#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);
}
Quindi, all'avvicinarsi di Y2K, questo file di implementazione verrebbe modificato come segue (tutto il resto non verrebbe toccato):
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;
}
Quando il client deve essere aggiornato per utilizzare la nuova versione (sicura per Y2K), non sono necessarie modifiche al codice. In realtà, si potrebbe anche non avere ricompilare: semplicemente ri-linking alla libreria di oggetti aggiornata (se è questo che si tratta) potrebbe essere sufficiente.
structè una scatola nera con interni sconosciuti. Se il client non conosce gli interni, non può mai accedervi direttamente e puoi cambiarli a piacimento. Questo è simile all'incapsulamento in OOP. Gli interni sono privati e si modifica l'oggetto solo con metodi pubblici.