Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
1

Нужны ли геттеры/сеттеры в чистом си?

05.12.2014, 15:45. Показов 3531. Ответов 34
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Есть ли пример ситуации, когда могут понадобиться геттеры и сеттеры в чистом си?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.12.2014, 15:45
Ответы с готовыми решениями:

Нужны ли геттеры и сеттеры
Переделываю программку с Qt C++ на python и там доступ к всем переменным через геттеры и сеттеры...

Оставлять ли геттеры-сеттеры если они не нужны
Заметил у себя привычку всегда генерировать геттеры-сеттеры к полям. В большинстве случаев они даже...

Как работают геттеры и сеттеры и зачем они нужны?
Не понимаю как они работают и зачем они нужны. Можно примеры и объяснения пожалуйста. Понял, что...

Геттеры и сеттеры
Всем привет , решал задачу с learn.js Решил ее, но до конца не разобрался почем в...

34
Guardian of Asgaard
377 / 319 / 197
Регистрация: 11.11.2013
Сообщений: 1,046
05.12.2014, 15:49 2
Инкапсуляция в чистом Си отсутствует, а значит геттеров и сеттеров в нём не существует. Они только в С++.
0
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
05.12.2014, 15:51  [ТС] 3
Цитата Сообщение от Darkrduk Посмотреть сообщение
Инкапсуляция в чистом Си отсутствует, а значит геттеров и сеттеров в нём не существует. Они только в С++.
В теории да.
А если для написания проекта должен использоваться именно язык Си, но потребовалась инкапсуляция какой-то локальной переменной?
А какие еще полезные функции могут выполнять Гет-Сет методы, кроме возвращения переменной и проверки валидности ее значения?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12460 / 7484 / 1754
Регистрация: 25.07.2009
Сообщений: 13,763
05.12.2014, 16:07 4
tiger(), сеттеры могут понадобиться, если нужно проверять значение, присваиваемое полю структуры. Но обязать пользователя устанавливать поля структур исключительно с их помощью - задача нетривиальная, и не уверен, что вообще решаемая. В С напрочь отсутствуют такие понятия, как инкапсуляция данных и прочие заморочки из ООП. Геттер (вернее функция его напоминающая) может пригодиться, когда нужно не просто возвращать какое-то поле структуры, а производить над возвращаемым значением какие-то действия. Но опять же ничто не помешает просто поля объекта структуры прочитать.
Другой вариант:
number_keeper.h
C
1
2
3
4
5
6
7
#ifndef _NUMBER_KEEPER_H_
#define _NUMBER_KEEPER_H_ 1
 
extern int get_number(void);
extern void set_number(int);
 
#endif
number_keeper.c
C
1
2
3
4
5
6
7
8
9
10
11
#include "number_keeper.h"
 
static int number;
 
int get_number(void) {
    return number;
}
 
void set_number(int n) {
    number = n;
}
app.c
C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
#include "number_keeper.h"
    
int main(void) {
    printf("%d\n", get_number());
    set_number(13);
    printf("%d\n", get_number());
    
    return 0;
}
Кроме, как используя геттер и сеттер, до переменной number из main не добраться.
1
Guardian of Asgaard
377 / 319 / 197
Регистрация: 11.11.2013
Сообщений: 1,046
05.12.2014, 16:07 5
Геттеры только возвращают значение, а в Сеттерах помимо присвоения значения и проверки валидности можно, например, добавить условие, что если мы присвоим значение а > 999, то b = 0;
0
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
05.12.2014, 16:11  [ТС] 6
Цитата Сообщение от easybudda Посмотреть сообщение
Кроме, как используя геттер и сеттер, до переменной number из main не добраться.
А было бы 100% равнозначно этому коду объявить number не static, а extern? Тогда бы она была доступна вне main
0
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
05.12.2014, 16:14 7
Цитата Сообщение от easybudda Посмотреть сообщение
Но обязать пользователя устанавливать поля структур исключительно с их помощью - задача нетривиальная, и не уверен, что вообще решаемая.
Ну я бы не сказал, что все так однозначно. Можно ведь дать пользователю
какой-нибудь <void *> (идиома "opaque handle") и пускай работает со
структурой через него. А объявления самой структуры он может и не видеть.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12460 / 7484 / 1754
Регистрация: 25.07.2009
Сообщений: 13,763
05.12.2014, 16:15 8
Цитата Сообщение от tiger() Посмотреть сообщение
А было бы 100% равнозначно этому коду объявить number не static, а extern?
Нет. Это разные модификаторы, и назначение у них разное. Если переменную number объявить, как extern, оно и не скомпилируется, т.к. просто не найдёт, где под эту переменную место выделено. static же в данном случае ограничивает область видимости текущим модулем.
0
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
05.12.2014, 16:19  [ТС] 9
Цитата Сообщение от easybudda Посмотреть сообщение
Нет. Это разные модификаторы, и назначение у них разное. Если переменную number объявить, как extern, оно и не скомпилируется, т.к. просто не найдёт, где под эту переменную место выделено. static же в данном случае ограничивает область видимости текущим модулем.
Я имел ввиду конечно не просто заменить static словом extern, а пользоваться данной переменной либо как static и читать с помощью "геттера" либо объявить в другом модуле ее как extern и иметь прямой доступ.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12460 / 7484 / 1754
Регистрация: 25.07.2009
Сообщений: 13,763
05.12.2014, 16:23 10
Убежденный, ну можно, конечно, и собственно сам факт наличия объекта какой-то структуры скрыть от пользователя - "дали тебе набор функций - пользуйся!" Но опять же код получится весьма незаурядный, а потому нужна очень веская причина, чтобы такие танцы на С вытанцовывать...

Добавлено через 3 минуты
Цитата Сообщение от tiger() Посмотреть сообщение
объявить в другом модуле ее как extern и иметь прямой доступ.
Ещё раз: если внутри модуля переменная объявлена, как static, в другом модуле сослаться на неё с помощью объявления extern не получится - всё равно не найдётся.
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.12.2014, 16:25 11
Цитата Сообщение от tiger() Посмотреть сообщение
потребовалась инкапсуляция
Объявление static аналогично private в C++, при этом файлы (как единицы компиляции) будут аналогами классов. Инициализацию и финализацию (взамен конструкторов и деструкторов) придется огранизовать самостоятельно.
0
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
05.12.2014, 16:26  [ТС] 12
Цитата Сообщение от easybudda Посмотреть сообщение
Ещё раз: если внутри модуля переменная объявлена, как static, в другом модуле сослаться на неё с помощью объявления extern не получится - всё равно не найдётся.
Еще раз. Вопрос.
Абсолютно одинаковы два следующих подхода или есть тот который все-таки чем-то лучше?

1 подход. В одном модуле объявить переменную static. Достучаться до нее из другого модуля с помощью getter-функции.
2 подход. В одном модуле объявить локальную переменную. В другом модуле объявить ее как extern. Обращаться к ней напрямую.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12460 / 7484 / 1754
Регистрация: 25.07.2009
Сообщений: 13,763
05.12.2014, 16:29 13
Цитата Сообщение от tiger() Посмотреть сообщение
Абсолютно одинаковы два следующих подхода или есть тот который все-таки чем-то лучше?
Как они могут быть абсолютно одинаковыми, если во втором случае Вы практически получаете доступ к самой переменной и можете устанавливать для неё любое значение? Накроется вся эта как бы инкапсуляция...
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.12.2014, 16:33 14
Цитата Сообщение от tiger() Посмотреть сообщение
объявить локальную переменную. В другом модуле объявить ее как extern
Это противоположные вещи. extern - значит глобальная.
0
4 / 4 / 1
Регистрация: 20.04.2011
Сообщений: 141
05.12.2014, 16:36  [ТС] 15
Цитата Сообщение от gazlan Посмотреть сообщение
Это противоположные вещи. extern - значит глобальная.
Согласен. Хотел подчеркнуть что не STATIC

Добавлено через 2 минуты
Цитата Сообщение от easybudda Посмотреть сообщение
Накроется вся эта как бы инкапсуляция...
А нужна ли она? В си?
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.12.2014, 16:46 16
Цитата Сообщение от tiger() Посмотреть сообщение
А нужна ли она?
Как способ управления сложностью - Divide et Impera.
0
Эксперт функциональных языков программированияЭксперт Java
4486 / 2721 / 485
Регистрация: 28.04.2012
Сообщений: 8,590
05.12.2014, 18:10 17
Лучший ответ Сообщение было отмечено easybudda как решение

Решение

Цитата Сообщение от Darkrduk Посмотреть сообщение
Инкапсуляция в чистом Си отсутствует, а значит геттеров и сеттеров в нём не существует. Они только в С++.
Че, серьезно?

C
1
2
3
4
5
6
typedef struct Foo Foo;
 
Foo* Falloc();
void Ffree(Foo*);
void Finit(Foo*, int, float);
void Fprint(Foo*);
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
 
struct Foo
{
    int x;
    float y;
};
 
Foo*
Falloc()
{
    return malloc(sizeof(Foo));
}
 
void
Ffree(Foo* f)
{
    free(f);
}
 
void
Finit(Foo *f, int x, float y)
{
    f->x = x;
    f->y = y;
}
 
void
Fprint(Foo *f)
{
    printf("Foo{%d, %f}", f->x, f->y);
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include "foo.h"
 
int
main(void)
{
    Foo *f;
    f = Falloc();
    Finit(f, 1, 2.3);
    Fprint(f);
    Ffree(f);
 
    printf("\n");
    return 0;
}
Bash
1
2
3
4
$ gcc -o main main.c foo.c
$ ./main
Foo{1, 2.300000}
$
Добавлено через 1 минуту
Цитата Сообщение от gazlan Посмотреть сообщение
Объявление static аналогично private в C++
Да ты шутишь?

Добавлено через 6 минут
Цитата Сообщение от easybudda Посмотреть сообщение
сеттеры могут понадобиться, если нужно проверять значение, присваиваемое полю структуры
Не обязательно. Сеттеры нужны тогда, когда логика изменения состояния объекта чуть сложнее, чем простая запись нового значения. Например, имеем объект "Термометр", хотим изменить температуру, на выбор 3 единицы измерения - K(ельвины), C(ельсии), F(аренгейты). Естественно значение храним в одной переменной (например в кельвинах, т.к. единица системы Си), но если присвоить ей напрямую значение в фаренгейтах, получится херня. Поэтому заводи сеттер, который принимает температуру в фаренгейтах и преобразует ее в кельвины, прежде чем записать в поле.

Другой пример -- GUI, совйства, паттерн Наблюдатель и т.п.

Так что "проверка значения" -- это лишь один из юз-кейсов и далеко не самый важный.
2
Модератор
Эксперт функциональных языков программированияЭксперт Python
36606 / 20334 / 4221
Регистрация: 12.02.2012
Сообщений: 33,653
Записей в блоге: 13
05.12.2014, 20:18 18
korvin_, а в Вашем коде можно получить доступ к полям структуры напрямую (в обход Finit)?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
05.12.2014, 21:04 19
Маленький вопросец. А какой смысл в инкапсуляции? Я вот вижу несколько (иерархию) смыслов.
1. Не дать ошибиться себе в большом проекте.
2. Избежать конфликтов в групповом дружественном проекте.
3. Не дать подсидеть себя в проекте, где каждый участник готов другому сделать бяку (такие проекты, ИМХО, обречены на провал, хотя можно представить себе ситуацию, где в учебном смысле они полезны. Типа - ведь дальше будешь жить с волками - учись выть)
4. Скрыть свою библиотеку (и данные!) от потенциальных пользователей, ибо дай им доступ - они такого наваяют...
5. Это мое нау-хау, и - руки прочь!
Возможно, есть и другие смыслы, которые я пропустил, но пока остановимся на этом.
1 и 2 легко решаются договором. Нарушителю делают предупреждение(2), затем гонят взашей. В случае 1 предлагается суицид.
Ситуации 3-5 сложнее. Но уверяю вас, что на чистом Си все это можно. Несколько сложнее, чем на плюсах. ибо он специально на это дело заточен, но можно.
Один из вариантов. Модуль обслуживающий некоторую структуру (struct) создает при запросе внутри себя экземпляр этой структуры (malloc). А запросившему дает Id. И внешний может оперировать только этим Id и запросами (функциями). Структуру он не знает, полей не видит. А исходники ты положил под подушку. Чем не инкапсуляция?
Кстати, Винда по этому пути и пошла. На чистом Си (пардон, сначала на паскале)
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.12.2014, 22:09 20
Чем выше забор, тем лучше соседи

Можете думать об этом как о водонепроницаемых переборках.

Инкапсуляция позволяет более гибкое, чем в C управление пространством имен (иерархией видимости) и повышает живучесть, благодаря более строгим проверкам на этапе компиляции. Обфускацмя в Windows (opacue data types) имеет иные цели.
1
05.12.2014, 22:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.12.2014, 22:09
Помогаю со студенческими работами здесь

Геттеры и сеттеры
Привет, я начинающий в программировании. Просматривал онлай уроки программирования Java и был урок...

Геттеры и Сеттеры
Сразу прошу прощение за может тупые вопросы я только начал познавать java.))Столкнулся с Геттерами...

Геттеры и сеттеры
Я недолго учу джаву, но уже заметил, что многие говорят, что геттеры и сеттеры это хорошо или...

Классы (сеттеры и геттеры)
У меня дан класс вектор. И 3 члена класса. И исходные данные, вектор а=а1,а2,а3 и вектор...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru