Поддержу VladD2 и AndreyFedotov (для ПК)
От: Аноним  
Дата: 08.11.04 22:42
Оценка: -7
Позволил себе вынести эту ветку
Автор: Павел Кузнецов
Дата: 07.11.04
сюда т.к. не могу писать в том форуме но хотелось бы поддержать этих товарищей. Заранее приношу извинения если что не так.

ПК>Средства для обеспечения инкапсуляции есть и в C. При этом получающаяся инкапсуляция ничуть не "меньше", чем в C++.

Средства для обеспечения инкапсуляции есть и в Си, но они намного примитивнее чем в С++, о чем и говорил VladD2. См. выделенный вопрос ниже чтобы понять почему "меньше."

ПК>Ты привел неэквивалентный с точки зрения инкапсуляции пример на C. Но это не означает, что нельзя написать эквивалентный в этом отношении пример на C. Вот он:

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

И думаете такое (ваш пример) нельзя сделать на С++?

ПК>Заголовочный файл:

ПК>
ПК>typedef int ErrorCode;

ПК>#define A_OK                 ((ErrorCode)0)

ПК>// Требования инкапсуляции не допускают установку
ПК>// отрицальтного значения свойству Val.
ПК>//
ПК>#define A_ERROR_INVALID_VAL  ((ErrorCode)-1)

ПК>typedef struct Atag A;

ПК>A*        create_A(void);
ПК>void      delete_A(A*);
ПК>int       A_getVal(A*);
ПК>ErrorCode A_setVal(A*, int);
ПК>

У Вас тут Atag не объявлен, и я не совсем уверен, что в Си можно писать struct Atag; чтобы объявить имя, но это неважно.

ПК>Файл с реализацией:

ПК>
ПК>. . .

ПК>struct Atag
ПК>{
ПК>   int _val;
ПК>};

ПК>A* create_A(void)
ПК>{
ПК>   A* a = (A*)malloc(sizeof(A));
ПК>   return a;
ПК>}

ПК>void delete_A(A* a)
ПК>{
ПК>   free(a);
ПК>}

ПК>int A_getVal(A* a)
ПК>{
ПК>   return a->_val;
ПК>}

ПК>ErrorCode setVal(A* a, int val)
ПК>{
ПК>   if (val < 0)
ПК>     return A_ERROR_INVALID_VAL;

   a->>_val = val;
ПК>   return A_OK;
ПК>}
ПК>


ПК>Использование:

ПК>
ПК>int main()
ПК>{
ПК>   A*        a;
ПК>   ErrorCode err_code;

ПК>   a = create_A();
ПК>   if (!a)
ПК>     return -1;

ПК>   err_code = 0;

ПК>   . . .

ПК>   if (err_code != A_OK)
ПК>     err_code = A_setVal(a, 123);  // OK

ПК>   if (err_code != A_OK)
ПК>     err_code = A_setVal(a, -123); // Облом в рантайме.

ПК>   if (err_code != A_OK)
     a->>_val = -123;  // Облом во время компиляции.

ПК>   delete_A(a);

ПК>   return err_code == A_OK ? 0 : -1;
ПК>}
ПК>

Ну а теперь сам вопрос: А слабо Вам с Вашей инкапсуляцией создать genuine local object? Без всяких там хэндлов или указателей... Создавать объект на хипе только для того, чтобы скрыть его детали — изврат.

>> Не думаю, что этот пример был действительно нужен.

Оказалось, что нужен т.к. позволил понять в чем заблуждается Павел, .

ПК>Отчего же, он вполне хорошо проиллюстрировал твою позицию, здорово сэкономив нам время на ненужной риторике.

Которая (позиция) тем не менее оказалась правильной (в отличии от Вашей).

ПК>Как видишь, C вполне позволяет писать код, эквивалентный в отношении инкапсуляции коду на C++.

Как видите, Павел, Си вполне не позволяет создать локальный объект, который бы делал "то, что нужно" в ответ на посылку какого-нибудь сообщения, выражаясь ООП терминологией.

ПК>Скажем, та же Win API в этом отношении вполне в порядке.

Win API Вы привели совершенно не к месту. Там структуры данных ядра находятся в виртуальном адресном пространстве самого ядра, и даже зная их описание, Вы все равно бы ничего не смогли сделать с ними. Использование хэндлов или дескрипторов является, имхо, единственным естественным решением для доступа к этим структурам данных, а не по-тому что "так инкапсуляция происходит лучше." Попробуйте использовать наследие, инкапсуляцию и полиморфизм в С++, чтобы добиться такого же эффекта, что и Win API со своими хэндлами, и увидите, что не так-то это и легко. Поэтому я и использую слово "естественный."

ПК>Это в теории. На практике можно наблюдать, что многие библиотеки и API, написанные на C, лучше скрывают детали своей реализации, чем аналогичные библиотеки и API на C++.

Это чем же? Забудьте о Win API т.к. говоря о них, мы говорим о структурах данных ядра и другом адресном пространстве...

Есть библиотеки на Си которые извращаются точно так же как и извратились Вы и возвращают либо какой-нибудь хэндл или указатель на объект в адресном пространстве процесса, но делается это не потому, что "инкапсуляция в Си лучше," а за неимением в Си того, что предоставляет нам С++ со своими public, protected и private. С++ в этом плане идет на шаг дальше, и поэтому Влад и говорит, что в Си инкапсуляция примитивнее чем в С++.

ПК>Попробуй, например, доступиться к внутренним структурам Windows — вряд ли это получится сделать легко: Win API достаточно хорошо изолирует тебя от внутренних деталей.

Еще бы! Структуры данных-то находятся в адресном пространстве ядра, . См. мое объяснение выше.

ПК>А теперь давай посмотрим, скажем, на MFC... Много переменных-членов public, protected, не говоря уже о различных "внутренних" функциях с доступом public, включенных в интерфейс класса просто потому что они нужны самой MFC.

MFC не является примером для подражания, и то, о чем Вы говорите сейчас, говорит о плохом дизайне а не о поддержке инкапсуляции в языках Си и С++.

ПК>На C++ легче организовать сокрытие данных (вообще-то это вовсе не эквивалентно инкапсуляции, но на этом можно сейчас не останавливаться). Но это вовсе не означает, что сокрытие данных будет практически более эффективно, чем в C.

Не совсем понимаю, что Вы имеете здесь в виду под эффективностью, но, как я уже заметил, с Вашей инкапсуляцией на Си вы не можете создать локальный объект, который бы просто "делал свою работу." А создовать объект на хипе, чтобы скрыть его данные — это просто изврат.

> Сравнение не корректно. Команда, которая делала API Windows — была на несколько порядков опытнее <...>

ПК>Я с этим не спорю. Я только привел пример того, что на C вполне возможно писать, не выпячивая детали реализации наружу; плюс пример того, что на C++ инкапсуляция автоматически "сама собой" тоже не возникает. Именно квалификация разработчиков, с моей точки зрения, и определяет "степень инкапсулированности" того, что получится в результате. И именно поэтому я скептически отношусь к заявлениям, скажем, о "большем совершенстве С+ с точки зрения инкапсуляции".
Так-то оно так, но вот С++ больше помогает программисту избежать ошибок (своими private и public) а вот Си — нет.

09.11.04 15:58: Перенесено из 'C/C++'
Re: Поддержу VladD2 и AndreyFedotov (для ПК)
От: MaximE Великобритания  
Дата: 09.11.04 05:52
Оценка: 1 (1) +3 -1
некто wrote:

[]

> Ну а теперь сам вопрос: А слабо Вам с Вашей инкапсуляцией создать genuine local object? Без всяких там хэндлов или указателей... Создавать объект на хипе только для того, чтобы скрыть его детали — изврат.


А как эту проблему решает C++? Там то же самое.

[]

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


Вы что-то путаете: public, protected и private — это не более чем спецификаторы доступа, которые ограничивают доступ, но реализацию не скрывают; к инкапсуляции они имеют малое отношение. Инкапсуляция — это когда состояние объекта можно наблюдать и изменять вызывая соответствующии функции объекта, а не доступаясь к состоянию на прямую. Можно создать структуру без спецификаторов доступа, но с состоянием и ф-циями членами, и наслаждаться инкапсуляцией.

[]

> Так-то оно так, но вот С++ больше помогает программисту избежать ошибок (своими private и public) а вот Си — нет.


В Python нет спецификаторов доступа (private, public...) — никто не хнычит, инкапсуляция не страдает, все счастливы. Мораль: какими бы языками не пользоваться, программирование — это дисциплина во всех значениях этого слова. Программисты на "продвинутых" C# с Java'ой могут такой чепухи понаписать...

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9 gamma
Re: Поддержу VladD2 и AndreyFedotov (для ПК)
От: Shady Россия  
Дата: 09.11.04 09:27
Оценка: +2
Здравствуйте, Аноним, Вы писали:

Это флецм черт возьми, и ему место именно там, откуда ветка приползла. Что так сложно зарегистрироваться и писать в любом форуме?
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Re: Поддержу VladD2 и AndreyFedotov (для ПК)
От: Кодт Россия  
Дата: 09.11.04 09:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну а теперь сам вопрос: А слабо Вам с Вашей инкапсуляцией создать genuine local object? Без всяких там хэндлов или указателей... Создавать объект на хипе только для того, чтобы скрыть его детали — изврат.


Чтобы сделать genuine local object, нужно знать, как минимум, его размер (и выравнивание). Ну, в общем-то, запросто...
#define A__SIZE 123
void  A__ctor(void* buf, ctor-args);
void  A__dtor(void* buf);

void* A__new(ctor-args)  { void* p = malloc(A__SIZE); A__ctor(p, ctor-args); return p; }
void  A__delete(void* p) { A__dtor(p); free(p); }

int  A__foo(void* p);
void A__bar(void* p, int);


int main()
{
  char a[A__SIZE];
  A__ctor(a);
  A__bar(a,123);
  printf("%d", A__foo(a));
  A__dtor(a);
}

Однако делать так — гораздо больший изврат, чем размещать объекты на куче.

И вообще, размещение объектов в статическом и автоматическом хранилище — это фича языка С++. Ну ещё TurboPascal 5.5-7.0. Больше никто так не делает — все в сад, то есть в кучу.
Перекуём баги на фичи!
Re[2]: Поддержу VladD2 и AndreyFedotov (для ПК)
От: folk Россия  
Дата: 09.11.04 12:59
Оценка:
MaximE:

> Вы что-то путаете: public, protected и private — это не более чем спецификаторы доступа, которые ограничивают доступ, но реализацию не скрывают; к инкапсуляции они имеют малое отношение. Инкапсуляция — это когда состояние объекта можно наблюдать и изменять вызывая соответствующии функции объекта, а не доступаясь к состоянию на прямую. Можно создать структуру без спецификаторов доступа, но с состоянием и ф-циями членами, и наслаждаться инкапсуляцией.


Что-то здесь не так
Какие задачи решает такая инкапсуляция?
Как называется концепция, для поддержки которой были введены спецификаторы доступа public, protected и private?

[]
Posted via RSDN NNTP Server 1.9 gamma
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[3]: Поддержу VladD2 и AndreyFedotov (для ПК)
От: MaximE Великобритания  
Дата: 14.11.04 00:37
Оценка: -1
Здравствуйте, folk, Вы писали:

F>MaximE:


>> Вы что-то путаете: public, protected и private — это не более чем спецификаторы доступа, которые ограничивают доступ, но реализацию не скрывают; к инкапсуляции они имеют малое отношение. Инкапсуляция — это когда состояние объекта можно наблюдать и изменять вызывая соответствующии функции объекта, а не доступаясь к состоянию на прямую. Можно создать структуру без спецификаторов доступа, но с состоянием и ф-циями членами, и наслаждаться инкапсуляцией.


F>Что-то здесь не так

F>Какие задачи решает такая инкапсуляция?

Решает пару задач — запрещает оперирование состоянием объекта напрямую — это то что делают private-public и интерфейсы; скрывает реализацию объекта — это то, что делают только интерфейсы (+pimpl) .

F>Как называется концепция, для поддержки которой были введены спецификаторы доступа public, protected и private?


См. выще. Не уверен, что была какая-то фундаментальная концепция.
Re[4]: Поддержу VladD2 и AndreyFedotov (для ПК)
От: folk Россия  
Дата: 14.11.04 04:27
Оценка: +1
MaximE:

> >> Вы что-то путаете: public, protected и private — это не более чем спецификаторы доступа, которые ограничивают доступ, но реализацию не скрывают; к инкапсуляции они имеют малое отношение. Инкапсуляция — это когда состояние объекта можно наблюдать и изменять вызывая соответствующии функции объекта, а не доступаясь к состоянию на прямую. Можно создать структуру без спецификаторов доступа, но с состоянием и ф-циями членами, и наслаждаться инкапсуляцией.

>
> F>Что-то здесь не так
> F>Какие задачи решает такая инкапсуляция?
>
> Решает пару задач — запрещает оперирование состоянием объекта напрямую — это то что делают private-public и интерфейсы; скрывает реализацию объекта — это то, что делают только интерфейсы (+pimpl) .

Не понял, как "структура без спецификаторов доступа, но с состоянием и ф-циями членами" запрещает оперирование состоянием объекта напрямую? Все же открыто для публики.

> F>Как называется концепция, для поддержки которой были введены спецификаторы доступа public, protected и private?

>
> См. выще. Не уверен, что была какая-то фундаментальная концепция.

Абзацем выше ты вроде согласился что public-private имеют отношение к инкапсуляции
Если хочешь поговорить об этом, то лучше это делать в топике "Суть понятия инкапсуляции" по соседству.

Вижу у меня серьезные проблемы с пониманием собеседников
Posted via RSDN NNTP Server 1.9 gamma
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.