То, кто спроектировал / разработало IOStreams C++, и это будут все еще считать хорошо разработанным сегодняшними стандартами? [закрытый]

Прежде всего может казаться, что я прошу субъективные мнения, но это не то, что я после. Я хотел бы услышать некоторые обоснованные аргументы по этой теме.


В надежде на получение некоторого понимания, как современные потоки / платформа сериализации должна быть разработана, я недавно вовлек себя копия книги Стандарт C++ IOStreams и Локали Angelika Langer и Klaus Kreft. Я полагал, что, если бы IOStreams не был хорошо разработан, он не превратил бы его в библиотеку стандарта C++ во-первых.

Считав различные части этой книги, я начинаю иметь сомнения, если IOStreams может выдержать сравнение с, например, STL с полной архитектурной точки зрения. Читайте, например, это интервью с Alexander Stepanov ("изобретатель" STL) для приобретения знаний о некоторых проектных решениях, которые вошли в STL.

Что удивляет меня в особенности:

  • Это, кажется, неизвестно, кто был ответственен за общий замысел IOSTREAM (я хотел бы считать некоторую справочную информацию об этом — кто-либо знает хорошие ресурсы?);

  • После того как Вы пашете под непосредственной поверхностью IOStreams, например, если Вы хотите расширить IOStreams с помощью своих собственных классов, Вы добираетесь до интерфейса с довольно загадочными и запутывающими именами функции членства, например. getloc/imbue, uflow/underflow, snextc/sbumpc/sgetc/sgetn, pbase/pptr/epptr (и существуют, вероятно, еще худшие примеры). Это делает его настолько тяжелее для понимания общего замысла и как единственные части сотрудничают. Даже книга, которую я упомянул выше, не помогает так многому (по моему скромному мнению).


Таким образом мой вопрос:

Если бы необходимо было судить по сегодняшним стандартам разработки программного обеспечения (если бы на самом деле существует какое-либо генеральное соглашение по ним), IOStreams C++ все еще считали бы хорошо разработанным? (Я не хотел бы улучшать свои навыки разработки программного обеспечения от чего-то, что это обычно считало устаревшим.)

125
задан Machavity 2 November 2018 в 18:15
поделиться

7 ответов

Несколько непродуманных идей нашли свое отражение в стандарте: auto_ptr , vector , valarray ] и экспорт , и это лишь некоторые из них. Поэтому я бы не стал рассматривать наличие IOStreams как признак качественного дизайна.

У IOStreams неоднозначная история. На самом деле они представляют собой переработку более ранней библиотеки потоков, но были созданы в то время, когда многие из сегодняшних идиом C ++ не существовали, поэтому у дизайнеров не было возможности оглянуться назад. Одна проблема, которая стала очевидной только со временем, заключалась в том, что практически невозможно реализовать IOStreams так же эффективно, как stdio C, из-за обильного использования виртуальных функций и пересылки во внутренние буферные объекты даже с самой тонкой степенью детализации, а также из-за некоторой непостижимой странности. в способах определения и реализации локалей. Признаюсь, у меня довольно расплывчатые воспоминания об этом; Я помню, как несколько лет назад он был предметом интенсивных дебатов на comp.lang.c ++. Moderated.

29
ответ дан 24 November 2019 в 01:02
поделиться

Что касается того, кто их разработал, то оригинальная библиотека была (что неудивительно) создана Бьярном Струструпом, а затем переработана Дейвом Пресотто. Затем она была переработана и снова реализована Джерри Шварцем для Cfront 2.0, используя идею манипуляторов от Эндрю Кенига. Стандартная версия библиотеки основана на этой реализации.

Источник "The Design & Evolution of C++", раздел 8.3.1.

40
ответ дан 24 November 2019 в 01:02
поделиться

Я размещаю это как отдельный ответ, потому что это чистое мнение.

Выполнение ввода и вывода (особенно ввода) - это очень, очень трудная задача, поэтому неудивительно, что библиотека iostreams полна ошибок и вещей, которые при идеальной ретроспективе можно было бы сделать лучше. Но мне кажется, что все библиотеки ввода/вывода, на каком бы языке они ни были, такие. Я никогда не использовал язык программирования, в котором система ввода/вывода была бы чем-то прекрасным, что заставляло бы меня благоговеть перед ее разработчиком. Библиотека iostreams действительно имеет преимущества, особенно перед библиотекой ввода/вывода языка C (расширяемость, безопасность типов и т.д.), но я не думаю, что кто-то считает ее примером отличного OO или общего дизайна.

16
ответ дан 24 November 2019 в 01:02
поделиться

(Этот ответ основан только на моем мнении)

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

2
ответ дан 24 November 2019 в 01:02
поделиться

Я всегда считал C ++ IOStreams плохо спроектированными: их реализация очень затрудняет правильную определите новый тип потока. они также смешивают функции io и функции форматирования (подумайте о манипуляторах).

Лично я считаю, что лучший дизайн и реализация потока, которые я когда-либо находил, лежит на языке программирования Ada. это модель развязки, удовольствие от создания потоков нового типа, а функции вывода всегда работают независимо от используемого потока. это благодаря наименее общему знаменателю: вы выводите байты в поток и все. потоковые функции заботятся о помещении байтов в поток, это не их работа, например, форматировать целое число в шестнадцатеричное (конечно, есть набор атрибутов типа, эквивалентный члену класса, определенному для обработки форматирования)

я бы хотел, чтобы C ++ был таким же простым в отношении потоков ...

{{1} }
10
ответ дан 24 November 2019 в 01:02
поделиться

Я думаю, что дизайн IOStreams великолепен с точки зрения расширяемости и полезности.

  1. Буферы потоков: посмотрите на расширения boost.iostream: создание gzip, tee, копирование потоков в несколько строк, создавать специальные фильтры и так далее. Без этого было бы невозможно.
  2. Интеграция локализации и интеграция форматирования. Посмотрите, что можно сделать:

    std::cout << as::spellout << 100 << std::endl;
    

    Можно напечатать: "сто" или даже:

    std::cout << translate("Good morning") << std::endl;
    

    Может напечатать "Bonjour" или "בוקר טוב" в соответствии с локалью, вложенной в std::cout!

    Такие вещи можно делать просто потому, что iostreams очень гибкие.

Можно ли сделать это лучше?

Конечно, можно! На самом деле есть много вещей, которые можно улучшить...

Сегодня довольно болезненно правильно выводить из stream_buffer, довольно нетривиально добавить дополнительную информацию о форматировании в поток, но возможно.

Но, оглядываясь на много лет назад, я все еще считаю, что дизайн библиотеки был достаточно хорош, чтобы принести много пользы.

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

10
ответ дан 24 November 2019 в 01:02
поделиться

Если бы вам пришлось судить по сегодняшним стандартам программной инженерии (если есть ли вообще какое-то общее соглашение по ним), то можно ли считать IOStreams все еще считались бы хорошо спроектированными? (Я бы не хотел улучшать свои навыки проектирования программного обеспечения на основе того, что обычно считается устаревшим.)

Я бы сказал НЕТ, по нескольким причинам:

Плохая обработка ошибок

Об ошибках следует сообщать с помощью исключений, а не с помощью operator void*.

Антипаттерн "зомби-объект" является причиной таких ошибок.

Плохое разделение между форматированием и вводом/выводом

Это делает объекты потока излишне сложными, поскольку они должны содержать дополнительную информацию о состоянии для форматирования, независимо от того, нужно оно вам или нет.

Это также увеличивает вероятность написания ошибок типа:

using namespace std; // I'm lazy.
cout << hex << setw(8) << setfill('0') << x << endl;
// Oops!  Forgot to set the stream back to decimal mode.

Если бы вместо этого вы написали что-то вроде:

cout << pad(to_hex(x), 8, '0') << endl;

Не было бы битов состояния, связанных с форматированием, и не было бы проблем.

Обратите внимание, что в "современных" языках, таких как Java, C# и Python, все объекты имеют функцию toString/ToString/__str__, которая вызывается подпрограммами ввода/вывода. AFAIK, только C++ делает это наоборот, используя stringstream в качестве стандартного способа преобразования в строку.

Плохая поддержка i18n

Вывод на основе Iostream разбивает строковые литералы на части.

cout << "My name is " << name << " and I am " << occupation << " from " << hometown << endl;

Формат строк помещает целые предложения в строковые литералы.

printf("My name is %s and I am %s from %s.\n", name, occupation, hometown);

Последний подход легче адаптировать к библиотекам интернационализации, таким как GNU gettext, поскольку использование целых предложений дает переводчикам больше контекста. Если ваша процедура форматирования строк поддерживает переупорядочивание (подобно параметрам POSIX $ printf), то она также лучше справляется с различиями в порядке слов между языками.

28
ответ дан 24 November 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: