Un posible escenario del mundo real en el que esto ocurriría es cuando una biblioteca de base de datos, escrita en los días en que el espacio en el disco duro era muy limitado, usaba un solo byte para almacenar el campo 'año' de una fecha (por ejemplo, 11-NOV-1973 tendría 73para el año). Pero, cuando llegó el año 2000, esto ya no sería suficiente, y el año tuvo que ser almacenado como un entero corto (16 bits). El encabezado relevante (muy simplificado) para esta biblioteca podría ser este:
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
Y un programa 'cliente' sería:
#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;
}
La implementación 'original':
#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);
}
Luego, en el enfoque de Y2K, este archivo de implementación se cambiaría de la siguiente manera (todo lo demás no se modifica):
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;
}
Cuando el cliente necesita ser actualizado para usar la nueva versión (segura para Y2K), no se requerirán cambios de código. De hecho, es posible que ni siquiera tenga que volver a compilar: simplemente volver a vincular a la biblioteca de objetos actualizada (si eso es lo que es) podría ser suficiente.
structes una caja negra con elementos internos desconocidos. Si el cliente no conoce las partes internas, nunca podrá acceder a ellas directamente y puede cambiarlas a voluntad. Esto es similar a la encapsulación en OOP. Los elementos internos son privados y solo cambia el objeto utilizando métodos públicos.