При определении нового struct
лучше определить также интерфейс для этого типа
(т.е. «сеттер» и «добытчика» функции) или для доступа пользователей непосредственно через .
и ->
операторов?интерфейс
EDIT
Plain C программирование
При определении нового struct
лучше определить также интерфейс для этого типа
(т.е. «сеттер» и «добытчика» функции) или для доступа пользователей непосредственно через .
и ->
операторов?интерфейс
EDIT
Plain C программирование
С C вы обычно не определяют сеттеров и добытчиками для каждого члена структуры.
Преимущества сеттеров и геттеров присутствуют на C++, потому что вы можете скрывать данные с помощью частных и защищенных. С C нет такой концепции частных и защищенных членов структуры.
Вы можете скрыть реализацию структуры посредством прямого объявления. Затем методы getter/setter могут использоваться для доступа к членам структуры. –
Если вы читаете чужой код, вы предпочли бы видеть:
setSomeValue(&aStruct, VALUE);
или:
aStruct.someValue = VALUE;
Синтаксис второй делает это очевидным, что поле aStruct создается. Во-первых, вы зависите от имен функций и переменных, выбранных программистом, чтобы получить эту информацию.
Нет причин, по которым вы не могли бы написать «aStruct.setSomeValue (VALUE)», предполагая, что правильная функция init задает некоторые указатели на функции. –
@Randy: как функция 'setSomeValue' знает, где находится структура в памяти? Статический указатель, настроенный подпрограммой init? –
Хороший вопрос! Я ничего не получил. –
В C, если вы создаете новую структуру, у нее уже есть встроенный/getter. Если вы используете имя переменной, вы используете varName.memberElement, и если вы используете указатель struct: pointer -> memberElement , Например:
struct Random
{
int temp;
};
Если мы создаем переменные структуры, struct Random example
тогда мы можем получить доступ и установить переменные с помощью. нотации.
example.temp = 12345;
Если мы создадим указатель на структуру, мы будем использовать -> обозначение.
struct Random element, *pointer;
pointer = &element;
Мы не установлен указатель, чтобы указать на элемент, а затем членам доступа,
pointer->temp = 12345;
Нет необходимости создавать отдельные интерфейсы и функции сеттер/геттер в C. Не делать больше работы для себя.
зависит от размера программы и предполагаемого использования. Имейте в виду, что все члены структуры являются общедоступными по умолчанию. Если вам нужно, чтобы они были частными, используйте вместо этого «класс».
Вы не замечаете, что это вопрос C и дали ответ на C++. –
@ Джонатан: В то время, когда я ответил, разъяснение об использовании С еще не было. – florin
В ответ на ответ Брайана Бонди, у вас не может есть геттеры и сеттеры; функции-члены просто не являются частью языка.
В C++, как правило, они не используются, потому что структуры почти всегда содержат, по соглашению, Обычные старые данные, и к элементам просто обращаются напрямую.
Это зависит от того, является ли ваша структура абстрактным типом данных или нет. Если вы сделаете определение структуры общедоступным в своем заголовке, то определение accessors не имеет никакого смысла - клиенты API могут по-прежнему читать/писать поля напрямую, а в C они имеют разумное ожидание, что оно будет работать.
С другой стороны, вы можете скрыть-структуру целиком, а только показать свою декларацию клиентам, как вид непрозрачной ручки:
foo.h:
typedef struct foo foo;
foo* foo_create();
void foo_free(foo*);
int foo_get_bar(foo*);
void foo_set_bar(foo*, int);
foo.cpp:
struct foo {
int bar;
};
foo* foo_create() { return malloc(sizeof(foo)); }
void foo_free(foo* p) { free(p); }
int foo_get_bar(foo* p) { return p->bar; }
void foo_set_bar(foo* p, int newval) { p->bar = nwval; }
client.cpp:
#include "foo.h"
foo* f = foo_create();
f->bar = 123; // compile error, bar is not defined
foo_set_bar(f, 123); // ok
Причина для этого: 1) инкапсуляция, то же, что и в OO, и 2) управление версиями - вы можете добавлять новые поля в свою структуру или реорганизовывать их свободно, а старый код останется двоично-совместимым.
Отличный ответ. –
Либо я делаю что-то неправильно (что очень вероятно), либо это не работает с gcc. Это работает только на C++? Я смущен расширением .cpp среди упоминаний о C-only. – Rafael
Прости, я понял. FTR, он работает на простом C: f ** может быть только указателем ** (foo *, not foo), если доступно объявление (не определение) типа. – Rafael
Это простой C или C++ также? – Ponting