Почему конструктор и метод open
классов std::( i | o) принимают имя файла в качестве параметра в виде const char*
вместо std::string
? Похоже, что создатели STL хотели бы использовать то, что они написали, вместо того, чтобы использовать тип, который они написали, чтобы заменить класс.
Почему (i | o) fstream принимает параметр const char * для имени файла?
Ответ 1
Класс std::string
реализует концепцию "изменяемая размер строки размера времени выполнения". Это когда этот класс следует использовать - когда вам нужна строка, размер которой известен только во время выполнения и который также можно изменять по времени выполнения. В ситуациях, когда вам не нужны эти функции с помощью std::string
, это избыток. По-видимому, авторы библиотеки не думали, что им нужна переменная размер времени выполнения для представления имени файла, поэтому они выбрали минималистическое решение: они использовали C-строку, где C-строка была достаточной. Это на самом деле очень хороший принцип для разработки интерфейсов библиотеки: никогда не требуйте того, что вам действительно не нужно.
Правда, в наши дни мы часто видим людей, которые поощряют программистов на С++ использовать std::string
всякий раз, когда им нужна строка, любая строка. Они часто утверждают, что классические строки C должны быть зарезервированы для кода C. В общем случае это фиктивная философия. Бесполезное использование сравнительно тяжелых объектов, таких как std::string
, более подходит для таких языков, как Java, но обычно неприемлемо в С++.
Да, в некоторых приложениях на С++ можно "обойтись без использования std::string
(" можно написать Java-программу на С++ "), но в такой общей низкоуровневой библиотеке, как С++ standard библиотека, заставляющая пользователя использовать std::string
без уважительной причины (то есть наложение ненужных требований) выглядела бы неплохо.
Ответ 2
Часть библиотеки string
была разработана после потоков, и никто не думал сделать очевидные изменения.
Это просто из политической и временной реальности, что они никогда не обходили это до отправки С++ 98, и никто не беспокоился о его возвращении, потому что вы всегда могли решить его с помощью .c_str()
.
С++ 0x исправляет это (см. 27.9.1.6).
Добро пожаловать в С++.
Ответ 3
Это, в основном, по историческим причинам, насколько я знаю. ifstream
и ofstream
существовали задолго до std::string
. Тогда они даже не имели std::
.
Ответ 4
Моя ставка заключается в том, что иерархия/библиотека iostream
(включая (i|o)fstream
) была изобретена/разработана отдельно от std::string
, и они только сначала встречались при объединении в библиотеке std
.
Во время изобретения iostream
было возможно много разных реализаций string
, которые шли вокруг и поддерживали максимальную переносимость, они решили сделать ставку на тип данных, который всегда доступен, и что простая строка char const*
c-style.
Ответ 5
Просто просматривая заголовок g++ <fstream>
, я заметил, что все ссылки на std::basic_string
или любой из его typedefs
находятся в разделах с разделителями #ifdef __GXX_EXPERIMENTAL_CXX0X__
.
Это говорит мне о том, что библиотека iostreams была разработана независимо от библиотеки строк, поэтому, если вы не использовали std::string
, вам не пришлось платить за нее (это исторически было очень важно принцип проектирования в С++). Это также объясняет, почему getline(std::istream&, std::string&)
- свободная функция, определенная в <string>
, а не функция-член, например istream::getline(char*, streamsize)
.
Это также говорит мне о стандартизации С++ 0x, рассматривая это как недостаток дизайна, и решил, что неудобство создания библиотеки iostreams, не зависящей от строковой библиотеки, не стоит того.
(Я не могу потрудиться, чтобы найти рабочий проект спецификации С++ 0x или систематически проверить все заголовки, связанные с iostreams, чтобы подтвердить это.)