Un scénario possible dans le monde réel où cela se produirait serait lorsqu'une bibliothèque de bases de données, écrite à l'époque où l'espace sur le disque dur était très limité, utilisait un seul octet pour stocker le champ 'année' d'une date (par exemple 11-NOV-1973 aurait 73
pour l'année). Mais, au moment de l'an 2000, cela ne serait plus suffisant, et l'année devait alors être stockée sous la forme d'un entier court (16 bits). L'en-tête pertinent (très simplifié) de cette bibliothèque pourrait être le suivant:
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
Et un programme «client» serait:
#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'implémentation «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);
}
Ensuite, à l'approche de Y2K, ce fichier d'implémentation serait modifié comme suit (tout le reste étant inchangé):
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;
}
Lorsque le client doit être mis à jour pour utiliser la nouvelle version (Y2K-safe), aucun changement de code n'est requis. En fait, vous n'aurez peut- être même pas à recompiler: une simple reconnexion à la bibliothèque d'objets mise à jour (si c'est ce que c'est) pourrait être suffisante.
struct
est une boîte noire avec des composants internes inconnus. Si le client ne connaît pas les internes, il ne pourra jamais y accéder directement et vous pourrez les changer à volonté. Ceci est similaire à l'encapsulation dans la POO. Les internes sont privés et vous ne modifiez l'objet qu'en utilisant des méthodes publiques.