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

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

У меня в настоящее время есть структура C с некоторыми участниками, которые должны быть так или иначе скрыты от остальной части приложения, поскольку их пользование является только внутренним. При изменении случайно одного из этого участники, вероятно, заставят библиотеку 'взбеситься'.

Там какое-либо 'обходное решение' должно скрыть тех участников так, чтобы они не могли быть доступными?

14
задан Josh Lee 26 March 2010 в 10:25
поделиться

4 ответа

Обычный прием таков:

/* 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, и является бременем обслуживания, если вы позже передумаете и захотите сделать что-то личное. Если вы не хотите извлекать из кода каждый последний цикл ЦП, просто используйте функции доступа.

16
ответ дан 1 December 2019 в 13:08
поделиться

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

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;
}
1
ответ дан 1 December 2019 в 13:08
поделиться

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

/* 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;
};

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

1
ответ дан 1 December 2019 в 13:08
поделиться

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

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

2
ответ дан 1 December 2019 в 13:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: