構造の「ユーザー」がそれを読み取る場所とデータがある場所の間にコードを挿入する機能がない限り、カプセル化ではありません。このようなシムを使用すると、構造の外部使用を変更せずに、構造の内部を変更できます。
あなたのソリューションはCで通常行われる方法の改善ですが、それをカプセル化するには、「外部」コードを変更せずにフィールドを単一の値から構築された値に変更できる必要があります。本当にカプセル化されています。
C では、これは通常、データを void ポインターの背後に隠すか、カプセル化されたコードの外部部分で宣言された (ただし未定義の) 構造体を使用することによって実行されます。
何とか
struct myStruct_t;
typedef struct myStruct_t myStruct;
extern myStruct * const ptrConstMyStruct;
// if you want a constructor, you need to declare the
// method here, because only blah.c will know the struct
// size with this solution.
myStruct * new_myStruct();
// methods
myStruct_setData(myStruct* obj, char c);
char myStruct_getData(myStruct* obj);
何とかc
#include "blah.h"
struct myStruct_t {
unsigned char data;
unsigned int intdata;
};
static myStruct thisIsMyModulesData;
// no need to make the struct const, just the pointer
// otherwise, we would have to break the const just to change
// data, which now will only be done within this file.
myStruct * const ptrConstMyStruct = &thisIsMyModulesData;
anotherFile.c
#include "blah.h"
// anotherFile "knows" of a struct called myStruct, but
// it doesn't know what it contains, or even it's size.
// this is no longer possible
// now "data" is encapsulated, and can be changed
// by reimplementing `myStruct_getData(...)`
// (as long as we don't change the method signature).
variable = ptrConstMyStruct->data;
// this is the "new" way
variable = myStruct_getData(ptrConstmyStruct);
// with the old, compiler error because of
// assigning a value to a const value.
ptrConstMyStruct->data = variable; //compile error!
^
(error occurs here)
// with the new, compiler error because of
// dereferencing a pointer to a unknown / incomplete type.
ptrConstMyStruct->data = variable; // compile error!
^
(error occurs here)
ご覧のとおり、エラーの場所によって、カプセル化の有無が異なります。ptrConstMyStruct->data
逆参照ではなく、代入でエラーをチェックすると、ポインタとデータの関係を変更できません。