2009-11-23 5 views
2
Структуры

При определении нового struct лучше определить также интерфейс для этого типа
(т.е. «сеттер» и «добытчика» функции) или для доступа пользователей непосредственно через . и -> операторов?интерфейс

EDIT
Plain C программирование

+0

Это простой C или C++ также? – Ponting

ответ

3

С C вы обычно не определяют сеттеров и добытчиками для каждого члена структуры.

Преимущества сеттеров и геттеров присутствуют на C++, потому что вы можете скрывать данные с помощью частных и защищенных. С C нет такой концепции частных и защищенных членов структуры.

+0

Вы можете скрыть реализацию структуры посредством прямого объявления. Затем методы getter/setter могут использоваться для доступа к членам структуры. –

0

Если вы читаете чужой код, вы предпочли бы видеть:

setSomeValue(&aStruct, VALUE); 

или:

aStruct.someValue = VALUE; 

Синтаксис второй делает это очевидным, что поле aStruct создается. Во-первых, вы зависите от имен функций и переменных, выбранных программистом, чтобы получить эту информацию.

+0

Нет причин, по которым вы не могли бы написать «aStruct.setSomeValue (VALUE)», предполагая, что правильная функция init задает некоторые указатели на функции. –

+0

@Randy: как функция 'setSomeValue' знает, где находится структура в памяти? Статический указатель, настроенный подпрограммой init? –

+0

Хороший вопрос! Я ничего не получил. –

0

В 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. Не делать больше работы для себя.

0

зависит от размера программы и предполагаемого использования. Имейте в виду, что все члены структуры являются общедоступными по умолчанию. Если вам нужно, чтобы они были частными, используйте вместо этого «класс».

+0

Вы не замечаете, что это вопрос C и дали ответ на C++. –

+0

@ Джонатан: В то время, когда я ответил, разъяснение об использовании С еще не было. – florin

-1

В ответ на ответ Брайана Бонди, у вас не может есть геттеры и сеттеры; функции-члены просто не являются частью языка.

В C++, как правило, они не используются, потому что структуры почти всегда содержат, по соглашению, Обычные старые данные, и к элементам просто обращаются напрямую.

13

Это зависит от того, является ли ваша структура абстрактным типом данных или нет. Если вы сделаете определение структуры общедоступным в своем заголовке, то определение 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) управление версиями - вы можете добавлять новые поля в свою структуру или реорганизовывать их свободно, а старый код останется двоично-совместимым.

+0

Отличный ответ. –

+0

Либо я делаю что-то неправильно (что очень вероятно), либо это не работает с gcc. Это работает только на C++? Я смущен расширением .cpp среди упоминаний о C-only. – Rafael

+0

Прости, я понял. FTR, он работает на простом C: f ** может быть только указателем ** (foo *, not foo), если доступно объявление (не определение) типа. – Rafael

Смежные вопросы