Есть ли какое-либо решение для создания члена структуры каким-то образом 'private' в C?

Я разрабатываю простую библиотеку в C, для моего личного + личного использования друзьями.

В настоящее время у меня есть структура C с некоторыми членами, которые должны быть каким-то образом скрыты от остальной части приложения, поскольку их использование является только внутренним. Изменяя случайно, один из этих членов, вероятно, сделает библиотеку "дикой".

Есть ли "обходной путь", чтобы скрыть эти элементы, чтобы они не были доступны?

Ответы

Ответ 1

Обычная техника такова:

/* foo.h */
typedef struct Foo Foo;

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

/* foo.c */
struct Foo {
  int private_var;
};

Вы можете частично скрыть данные, указав Foo в заголовке и FooPrivate в файле .c, таким образом:

struct FooPrivate {
  Foo public_stuff;
  int private_var;
}

Но тогда ваша реализация должна отбросить назад и вперед между Foo и FooPrivate, которые я считаю королевской PITA, и это бремя обслуживания, если вы передумаете позже и хотите сделать что-то частное. Если вы не хотите, чтобы каждый последний цикл процессора вышел из кода, просто используйте функции доступа.

Ответ 2

Марсело Кантос уже дал вам ответ. Для получения более подробной информации вы должны посмотреть, как структура FILE эффективно скрывается в большинстве библиотек удержания.

Вы бы заметили, что структура FILE сама по себе никогда не доступна для пользователя, нам доступны только интерфейсы и Opaque FILE *.

Ответ 3

В основном идея состоит в том, чтобы переименовать переменные структуры с чем-то вроде хэша и записывать функции (которые могли бы представлять собой мимические методы на языках OO) для доступа к ним. В идеале у вас должны быть указатели на функции для этих функций в вашей структуре, чтобы вы не должны вызвать внешнюю функцию и передать ей hte struct, кого вы хотите добавить. Однако синтаксис указателя функции не известен как самый красивый. Простой пример, который может прояснить то, что было сказано ранее Марсело:

struct Car {
    int _size;
    char _colour[10];

};

typedef struct Car Car;


int main (int argc, char **argv) {   
    Car *myCar= malloc(sizeof(Car));
    myCar->_size=5; /* accessing it directly just to set up a value, you shold have an
                       accessor function really */

    printf("car size is: %i \n",getCarSize(myCar));
    free(myCar);
}




int getCarSize(Car *myCar) {
     return myCar->_size;
}

Ответ 4

Я согласен с Marcelo Cantos, но также предлагаю просто добавить указатель внутри "общедоступной" структуры, которая указывает на содержимое "private", i.e:

/* foo.h */
typedef struct Bar Bar;
typedef struct Foo 
{
   int public;
   Bar* private;
} Foo;

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

/* foo.c */
struct Bar 
{
  int private_var;
};

Этот подход похож на идеал "пимпла". Самый простой подход - сделать то, что предложил Марсело Кантос.