これが発生する可能性のある現実的なシナリオは、ハードディスク領域が非常に制限されていた日に書かれたデータベースライブラリが1バイトを使用して日付の「年」フィールドを格納した場合です(例:11-NOV-1973持っているでしょう73
)年。しかし、2000年になると、これではもはや十分ではなく、その年は短い(16ビット)整数として格納する必要がありました。このライブラリに関連する(大幅に簡略化された)ヘッダーは次のようになります。
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
そして「クライアント」プログラムは次のようになります:
#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;
}
「元の」実装:
#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);
}
次に、Y2Kのアプローチで、この実装ファイルは次のように変更されます(その他はすべて変更されません)。
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;
}
新しい(Y2Kセーフ)バージョンを使用するようにクライアントを更新する必要がある場合、コードを変更する必要はありません。実際、再コンパイルする必要がない場合もあります。更新されたオブジェクトライブラリに再リンクするだけで十分です(それがそうである場合)。
struct
は、内部が不明なブラックボックスです。クライアントが内部を知らない場合、クライアントは直接それらにアクセスできず、自由に変更できます。これは、OOPのカプセル化に似ています。内部はプライベートであり、パブリックメソッドを使用してのみオブジェクトを変更します。