Есть способ скрыть реализацию структуры внутри модуля. Например:
/* file.h */
// Только объявление структуры, без определения
struct s;
// Можно создавать функции, которые принимают указатель на такую структуру или возвращают его.
bool s_is_good( struct s* some_struct );
/* Нельзя:
bool s_is_good( struct s some_struct );
Мы не знаем устройство s !
*/
void s_init( struct s** inst );
/* file.c */
struct s { int x; }
// Мы знаем внутреннее устройство структуры поэтому можем обращаться к её полям
bool s_is_good( struct s* some_struct ) {
return x > 0;
}
Только в file.c
можно работать с полями структуры struct s
. В других файлах нельзя:
- Создавать переменные типа
struct s
; - Принимать такую структуру как аргумент функции или возвращать эту структуру по значению из функций.
Преимущества
- Инкапсуляция: можно как угодно менять порядок полей и их количество, остальная часть программы не заметит этого. Её даже можно не перекомпилировать! Особенно удобно для библиотек.
Недостатки
- Дополнительный уровень косвенности, надо обращаться по указателю, может плохо сказаться на производительности,
- Неудобство. Например,
init
методы вынуждены принимать указатель на указатель:
/* не файл file.c */
...
struct s* variable = NULL;
s_init( &s ); // теперь s указывает на инициализированный экземпляр структуры struct s