Почему эти C ++ 11 новые функции заголовка <string>
(stod
, stof
, stoull
) не является членом функции string
учебный класс ?
Не более совместим с C ++ для написания mystring.stod(...)
скорее, чем stod(mystring,...)
?
Для многих это сюрприз, но C ++ не Объектно-ориентированный язык (в отличие от Java или C #).
C ++ — это мультипарадигмальный язык, поэтому он старается использовать лучший инструмент для работы, когда это возможно. В этом случае свободная функция это правильный инструмент.
директива: Предпочитать не являющиеся членами не дружественные функции функциям-членам (из Эффективного C ++, пункт 23)
причина: функция-член или функция-друг имеет доступ к внутренним объектам класса, тогда как функция, не являющаяся членом-другом, не имеет доступа; следовательно, используя функцию, не являющуюся членом, не являющуюся другом увеличивает инкапсуляцию.
исключение: когда функция-член или функция-друг обеспечивает значительное преимущество (например, производительность), тогда стоит задуматься, несмотря на дополнительную связь. Например, даже если std::find
работает очень хорошо, ассоциативные контейнеры, такие как std::set
обеспечить функцию-член std::set::find
который работает в O (log N) вместо O (N).
Основная причина в том, что они не принадлежат там. Oни
на самом деле не имеет ничего общего со строками. Остановись и подумай
об этом. Пользовательские типы должны следовать тем же правилам, что и
встроенные типы, поэтому каждый раз, когда вы определяете новый тип пользователя,
вам нужно добавить функцию к std::string
, Это будет
на самом деле возможно в C ++: если std::string
был член
шаблон функции to
без общей реализации, вы
можно добавить специализацию для каждого типа и вызвать
str.to<double>()
или же str.to<MyType>()
, Но это действительно
то, что ты хочешь. Это не кажется мне чистым решением,
чтобы каждый писал новый класс, чтобы добавить
специализация на std::string
, Положить такие вещи
в классе строки убивает его, и на самом деле наоборот
того, что ОО пытается достичь.
Если Вы должны были настаивать на чистой ОО, они должны были бы быть
Члены double
, int
и т. д. (действительно, конструктор.
это то, что делает Python, например.) C ++ не настаивает на чистом
ОО, и не допускает основных типов, таких как double
а также int
в
есть члены или специальные конструкторы. Так что бесплатные функции
и приемлемый раствор, и единственный чистый раствор
возможно в контексте языка.
FWIW: преобразования в / из текстового представления всегда
деликатная проблема: если я делаю это в целевом типе, то я
ввел зависимость от различных источников и приемников текста
в типе цели — и они могут изменяться во времени. Если я сделаю это в
тип источника или приемника, я делаю их в зависимости от типа
будучи обращенным, что еще хуже. Решение C ++ заключается в
определить протокол (в std::streambuf
), где пользователь пишет
новая бесплатная функция (operator<<
а также operator>>
) обрабатывать
преобразования и рассчитывает на разрешение перегрузки оператора в
найти правильную функцию. Преимущество свободной функции
Решение заключается в том, что преобразования не являются частью данных
тип (который, следовательно, не должен знать источников и поглотителей), ни
тип источника или приемника (который, таким образом, не должен знать о
пользовательские типы данных). Похоже, лучшее решение
мне. И функции как stod
это просто удобные функции,
которые делают одно особенно частое использование легче писать.
На самом деле это некоторые служебные функции, и они не должны находиться внутри основного класса. Подобные служебные функции, такие как atoi, atof определены (но для char *) внутри stdlib.h, и они тоже являются автономными функциями.