Часто, по соглашению, закрытый член имеет дополнительное подчеркивание в своем имени или что-то вроде _pri
.Или, возможно, комментарий.Этот метод не выполняет принудительную проверку компилятором, чтобы убедиться, что никто не обращается к этим полям ненадлежащим образом, но служит предупреждением для всех, кто читает декларацию struct
, что содержимое - это детали реализации, и они не должны заглядывать или тыкать в них.
Еще одна распространенная техника - показать вашу структуру как неполный тип.Например, в вашем заголовочном файле вы можете иметь:
struct my_struct;
void some_function(struct my_struct *);
И в реализации, или какой-то внутренний заголовок, который не доступен пользователям библиотеки, у вас есть:
struct my_struct
{
/* Members of that struct */
};
Вы также можете делать аналогичные трюки с указателями void, которые приводятся в нужное место в «приватной» части кода.Этот подход теряет некоторую гибкость (например, у вас не может быть выделенного в стеке экземпляра неопределенного типа), но это может быть приемлемым.
Если вы хотите иметь смесь частных и открытых членов,Вы можете сделать то же самое, что и выше, но сохранить частный указатель структуры как член общедоступного и оставить его неполным для публичных потребителей библиотеки.
Хотя это приводит к некоторой косвенности, которая может повредитьспектакль.Есть некоторые (как правило, непереносимые, но будут работать на приемлемых компиляторах) хитрости типа, которые вы также можете использовать:
struct public_struct
{
int public_member;
int public_member2;
/* etc.. */
};
struct private_struct
{
struct public_struct base_members;
int private_member1;
int private_member2;
};
void some_function(struct public_struct *obj)
{
/* Hack alert! */
struct private_struct *private = (struct private_struct*)obj;
}
Это также предполагает, что вы не можете хранить эти объекты в стеке или встатическое хранилище или получить размер во время компиляции.