Язык С и инкапсуляция
От: alien3128  
Дата: 14.05.15 05:41
Оценка:
Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?
Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.
Re: Язык С и инкапсуляция
От: _NN_ www.nemerleweb.com
Дата: 14.05.15 06:00
Оценка: +4
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

Функции работы с файлом как раз являются таким примером.

// Только объявляем
struct FILE;

FILE* f = fopen(...); // Создание объекта
fprintf(f, "%s", "A"); // Работа с объектом
fclose(f); // Разрушение объекта


Реализация например может быть такой
// Здесь детали реализации
struct FILE
{
 char path[100];
}
 
static private_fopen(...) {return malloc(sizeof(FILE)};

FILE* fopen(...) { return private_fopen(...) }
void fprintf(FILE* f, char const* fmt, ...) { ... }
void fclose(FILE* f) { free(f); }


Как можно видеть детали 'класса' FILE скрыты от нас, и работать с ним возможно только через публичные фукнции.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Язык С и инкапсуляция
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.15 08:57
Оценка:
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

Выше привели пример FILE*, он хорош и иллюстративен (используем для инкапсуляции систему модулей, вытаскиваем в заголовочники безликие дескрипторы). Но это только начало разговора. Если вы всерьёз планируете писать в ООП-стиле на C, там внутри лежит ещё много граблей, поэтому рекомендую вначале ознакомиться со state-of-art решением: системой типов и объектов GTK+.
Re[2]: Язык С и инкапсуляция
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.15 09:04
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Функции работы с файлом как раз являются таким примером.


Мне нравится обсуждение возможных проблем концепции opaque pointer, которая лежит в основе FILE*

Автор справедливо замечает: решение с opaque data type обрекает вас на выделение объектов в куче. Но это иногда может быть не совсем эффективно. А иногда -- совсем не эффективно. Как решение автор предлагает shadow data types:

      typedef struct  
      {  
        unsigned char size_shadow[16];  
      } wibble;  
 
      void wopen(wibble *, int);


В инкапсулированной части:

    typedef struct  
    {  
        grommet g;  
        flange f;  
    } wibble_rep;


Это позволяет даже на C размещать инкапсулированные объекты на стеке.
Re[3]: Язык С и инкапсуляция
От: _NN_ www.nemerleweb.com
Дата: 14.05.15 10:03
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Здравствуйте, _NN_, Вы писали:


_NN>>Функции работы с файлом как раз являются таким примером.


T>Мне нравится обсуждение возможных проблем концепции opaque pointer, которая лежит в основе FILE*


T>Автор справедливо замечает: решение с opaque data type обрекает вас на выделение объектов в куче. Но это иногда может быть не совсем эффективно. А иногда -- совсем не эффективно. Как решение автор предлагает shadow data types:

Можно еще через alloca выкрутиться или VLA C99.
Например

size_t sizeof_FILE(); 

FILE* f = (FILE*)alloca(sizeof_FILE()); // Выделяем на стеке

// Или так C99
char c[sizeof_FILE()];
FILE* f = (FILE*)&c[0];

fcreate(f); // Вызываем конструктор


Можно обернуть в макрос для удобства.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Язык С и инкапсуляция
От: MasterZiv СССР  
Дата: 14.05.15 16:14
Оценка:
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

0) Объект -- структура.
1) Структура объявляется в двух видах, в анонимном публичном, который содержит только один массив байт, который резервирует нужный объем
данных, и в приватном внутреннем, где расписаны все поля. Первая структура не нужна, если клиента ограничить, что он может хранить объекты в своей памяти
только по ссылке. Тогда указатель на первую структуру заменяется на указатель на void (он же HANDLE).
2) Вся реализация выполняется в отдельном модуле (исходном файле). Заголовки делятся также на публичные и приватные. Клиенту класса приватные заголовки
не даются.
3) создаётся полный набор функций, манипулирующих данными объектами, часто включая создание и удаление объектов.
Re[4]: Язык С и инкапсуляция
От: Ops Россия  
Дата: 14.05.15 16:33
Оценка: :)
Здравствуйте, _NN_, Вы писали:

_NN>Можно еще через alloca


_NN>Можно обернуть в макрос для удобства.


Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[2]: Язык С и инкапсуляция
От: drewet Нигерия  
Дата: 14.05.15 16:58
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Здравствуйте, alien3128, Вы писали:


A>>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

MZ>0) Объект -- структура.

MZ>1) Структура объявляется в двух видах, в анонимном публичном, который содержит только один массив байт, который резервирует нужный объем
MZ>данных, и в приватном внутреннем, где расписаны все поля. Первая структура не нужна, если клиента ограничить, что он может хранить объекты в своей памяти
MZ>только по ссылке. Тогда указатель на первую структуру заменяется на указатель на void (он же HANDLE).
MZ>2) Вся реализация выполняется в отдельном модуле (исходном файле). Заголовки делятся также на публичные и приватные. Клиенту класса приватные заголовки
MZ>не даются.
MZ>3) создаётся полный набор функций, манипулирующих данными объектами, часто включая создание и удаление объектов.

intptr_t
Re[2]: Язык С и инкапсуляция
От: bazis1 Канада  
Дата: 14.05.15 22:20
Оценка:
Здравствуйте, Tilir, Вы писали:

T>Выше привели пример FILE*, он хорош и иллюстративен (используем для инкапсуляции систему модулей, вытаскиваем в заголовочники безликие дескрипторы). Но это только начало разговора. Если вы всерьёз планируете писать в ООП-стиле на C, там внутри лежит ещё много граблей, поэтому рекомендую вначале ознакомиться со state-of-art решением: системой типов и объектов GTK+.

жуткое извращение, кстати. в духе "мы религиозно не будем писать на С++, поэтому возьмем и переизобретем большую часть его функционала, используя убогий синтаксис и препроцессор".
Re: Язык С и инкапсуляция
От: bazis1 Канада  
Дата: 14.05.15 22:21
Оценка: +1
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.
способов может быть много, вот только вопрос — зачем, когда C++ позволяет получить не менее эффективный код с меньшими трудозатратами?
Re[3]: Язык С и инкапсуляция
От: Tilir Россия http://tilir.livejournal.com
Дата: 15.05.15 03:55
Оценка: +1
Здравствуйте, bazis1, Вы писали:

B>жуткое извращение, кстати. в духе "мы религиозно не будем писать на С++, поэтому возьмем и переизобретем большую часть его функционала, используя убогий синтаксис и препроцессор".


Основные приемы ООП были придуманы задолго до C++ и не зависят по сути от языка программирования. Никакого переизобретения.

Для выбора языка C у авторов были причины. Например, к тому времени у C уже был стандартизованный ABI, а у C++ его нет до сих пор. Но писать на C++ там тоже можно, для этого есть языковой биндинг gtkmm. А также биндинги под другие языки в количестве.
Re: Язык С и инкапсуляция
От: Cruser Украина  
Дата: 16.05.15 11:44
Оценка:
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

Только через указатели, и только на неполный тип. Т.е. в хедере что-то типа typedef struct MyData_t* Handle; Но сама структура определена в си-файле. А функции принимают объект типа Handle.
Re: Язык С и инкапсуляция
От: Анатолий Широков СССР  
Дата: 19.05.15 15:54
Оценка: +1
Здравствуйте, alien3128, Вы писали:

A>Коллеги, подскажите, как на языке С можно эмулировать такое свойство ООП, как инкапсуляция?

A>Т.е. нужно иметь объект, все данные которого являются приватными. И должна быть возможность создавать неограниченное количество однотипных объектов.

В этой теме многие посоветовали в публичный интерфейс выставить указатель на неполный тип, а в реализации использовать полный. Но даже при сокрытии реального типа от клиента никто не запрещает исследовать память по полученному указателю и ее каким-либо образом модифицировать. В свое время MS, защищая свои структуры WINAPI, озаботилась подобным и перешла на фиктивные HANDLE, являющиеся ничем иным как ключем некой внутренней структуры, по которому реализация получает реально скрытые от глаз клиента данные. Эскиз:

// interface.h

typedef int HANDLE;

HANDLE open();
void use(HANDLE);
void close(HANDLE);

// interface.c
#include "interface.h"

const int N=16;

struct data {
   int opened;
   char filename[128];
} buffer[N] = {0};

HANDLE open() 
{
   int h = 0;
   // find free handle
...
   return h;
}

void use(HANDLE h) 
{
   struct data* p = &buffer[h];
   ...
}

void close(HANDLE h)
{
   buffer[h].opened = 0;
}
Отредактировано 19.05.2015 17:57 Анатолий Широков . Предыдущая версия . Еще …
Отредактировано 19.05.2015 17:09 Анатолий Широков . Предыдущая версия .
Отредактировано 19.05.2015 16:06 Анатолий Широков . Предыдущая версия .
Отредактировано 19.05.2015 15:55 Анатолий Широков . Предыдущая версия .
Re[2]: Язык С и инкапсуляция
От: Dair Россия  
Дата: 19.05.15 16:29
Оценка: +1
Здравствуйте, bazis1, Вы писали:

B>способов может быть много, вот только вопрос — зачем, когда C++ позволяет получить не менее эффективный код с меньшими трудозатратами?


Существуют продукты, где нет C++. Вот, например, линуксовое ядро (было когда-то, давно не смотрел).
Наверно, какое-нибудь ещё ядро тоже написано целиком на C.

Или микроконтроллер без компилятора C++ я вот тоже в своей жизни встречал. Или, конечно, с C++ но памяти типа 4 кбайта — "не лезет".
Ну, в общем, есть случаи, когда C практичнее.
Re[3]: Язык С и инкапсуляция
От: bazis1 Канада  
Дата: 19.05.15 17:11
Оценка: +2
Здравствуйте, Dair, Вы писали:

D>Здравствуйте, bazis1, Вы писали:


B>>способов может быть много, вот только вопрос — зачем, когда C++ позволяет получить не менее эффективный код с меньшими трудозатратами?


D>Существуют продукты, где нет C++. Вот, например, линуксовое ядро (было когда-то, давно не смотрел).

D>Наверно, какое-нибудь ещё ядро тоже написано целиком на C.
Я и говорю, религиозные заморочки.

D>Или микроконтроллер без компилятора C++ я вот тоже в своей жизни встречал.

Только если проект имеет корни в 70х-80х годах. Сейчас в любой нише цена/мощность есть контроллеры, поддерживаемые GCC.

D>Или, конечно, с C++ но памяти типа 4 кбайта — "не лезет".

Вы просто пользоваться им не умеете. Я в свое время писал на C++ под AVR с 512 байтами (!) памяти. Inline и шаблоны позволяли переложить вещи типа "а теперь этот протокол должен использовать SPI вместо USART" на компилятор, вместо программиста. Просто не надо STL с динамической памятью туда пихать и все будет хорошо.
D>Ну, в общем, есть случаи, когда C практичнее.
При условии, что вы не умеете эффективно выбрать нужный subset С++ и пользоваться им.
Re[4]: Язык С и инкапсуляция
От: Stanislav V. Zudin Россия  
Дата: 19.05.15 17:21
Оценка:
Здравствуйте, bazis1, Вы писали:


D>>Существуют продукты, где нет C++. Вот, например, линуксовое ядро (было когда-то, давно не смотрел).

D>>Наверно, какое-нибудь ещё ядро тоже написано целиком на C.
B>Я и говорю, религиозные заморочки.

D>>Или микроконтроллер без компилятора C++ я вот тоже в своей жизни встречал.

B>Только если проект имеет корни в 70х-80х годах. Сейчас в любой нише цена/мощность есть контроллеры, поддерживаемые GCC.

Штатный компилятор для zOS до сих пор С++ толком не поддерживает, даже '03. Так что приходится писать на Си времен K&R.
10 лет назад та же проблема была с HP-UX, не знаю, улучшилось ли что-нибудь сейчас.

хъ

D>>Ну, в общем, есть случаи, когда C практичнее.

B>При условии, что вы не умеете эффективно выбрать нужный subset С++ и пользоваться им.


Это верно, куда уж нам...
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Язык С и инкапсуляция
От: Анатолий Широков СССР  
Дата: 19.05.15 17:30
Оценка:
Здравствуйте, bazis1, Вы писали:

Недавно писал для pic16 (microchip), в наличии есть только XC8 для этого камня. Так что, ты уж чего-то шашкой размахался на счет вездесущности С++.
Re[5]: Язык С и инкапсуляция
От: bazis1 Канада  
Дата: 19.05.15 19:45
Оценка: :)
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Здравствуйте, bazis1, Вы писали:


АШ>Недавно писал для pic16 (microchip), в наличии есть только XC8 для этого камня. Так что, ты уж чего-то шашкой размахался на счет вездесущности С++.

мертвая платформа с меньше 0.1% долей рынка. мимо.
Re[5]: Язык С и инкапсуляция
От: bazis1 Канада  
Дата: 19.05.15 19:49
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Штатный компилятор для zOS до сих пор С++ толком не поддерживает, даже '03. Так что приходится писать на Си времен K&R.

SVZ>10 лет назад та же проблема была с HP-UX, не знаю, улучшилось ли что-нибудь сейчас.
это обычно означает, что платформа давно умерла, под нее ничего не пишут и, соответственно, нет смысла обновлять компилятор. Я не спорю, что в любой нише можно найти древнюю платформу, последний активный разработчик которой умер от старости в 199x году и там нет C++-компилятора. Я лишь утверждаю, что ориентироваться на такие платформы в 2015 году — странное занятие.
Re[6]: Язык С и инкапсуляция
От: Stanislav V. Zudin Россия  
Дата: 19.05.15 19:54
Оценка:
Здравствуйте, bazis1, Вы писали:

SVZ>>Штатный компилятор для zOS до сих пор С++ толком не поддерживает, даже '03. Так что приходится писать на Си времен K&R.

SVZ>>10 лет назад та же проблема была с HP-UX, не знаю, улучшилось ли что-нибудь сейчас.
B>это обычно означает, что платформа давно умерла, под нее ничего не пишут и, соответственно, нет смысла обновлять компилятор. Я не спорю, что в любой нише можно найти древнюю платформу, последний активный разработчик которой умер от старости в 199x году и там нет C++-компилятора. Я лишь утверждаю, что ориентироваться на такие платформы в 2015 году — странное занятие.

Это означает, что IBM, который развивает свои мейнфреймы, клал с прибором на мнение голодранцев и продолжает успешно окучивать больших и богатых клиентов. А для этих клиентов приходится разрабатывать софт.
_____________________
С уважением,
Stanislav V. Zudin
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.