Подтвердить что ты не робот

Зачем использовать std::string над строками c-style в С++?

"Всегда нужно использовать std::string по строкам c-style (char *)" - это совет, который подходит почти каждый исходный код размещен здесь. Хотя совет, без сомнения, хорош, актуальные вопросы, которые рассматриваются, не позволяют подробно рассмотреть аспект вопроса почему?. Этот вопрос должен служить в качестве заполнителя для того же самого.

Хороший ответ должен охватывать следующие аспекты (подробно):

  • Зачем использовать std::string над строками c-style в С++?
  • Каковы недостатки (если таковые имеются) практики, упомянутой в #1?
  • Каковы сценарии, где противоположность рекомендаций, упомянутых в #1, является хорошей практикой?
4b9b3361

Ответ 1

  • std::string управляет собственной памятью, поэтому вы можете легко копировать, создавать и уничтожать их.
  • Вы не можете использовать свой собственный буфер как std::string.
  • Вам нужно передать строку c/buffer к тому, что ожидает взять на себя ответственность за буфер, например, от библиотеки сторонних C.

Ответ 2

Ну, если вам просто нужен массив символов, std::string дает мало преимуществ. Но с этим сталкиваешься, как часто это происходит? Обертывая массив char с дополнительными функциями, такими как std::string, вы получаете как мощность, так и эффективность для некоторых операций.

Например, для определения длины массива символов требуется "подсчет" символов в массиве. Напротив, std::string обеспечивает эффективную работу для этой конкретной задачи. (см. fooobar.com/questions/85652/...)

  • Для мощности, эффективности и здравомыслия
  • Увеличенный объем памяти, чем "просто" массив char
  • Когда вам просто нужен массив символов

Ответ 3

3) Совет всегда использует string, конечно же, должен быть принят с обрывом здравого смысла. Строковые литералы const char[], и если вы передадите литерал функции, которая принимает const char* (например, std::ifstream::open()), нет никакой точки, обертывающей ее в std::string.

Ответ 4

A char * - это в основном указатель на символ. То, что C часто делает, указывает на то, что этот указатель указывает на первый символ в массиве.

An std::string - это класс, который очень похож на вектор. Внутри он обрабатывает хранилище массива символов и предоставляет пользователю несколько функций-членов для управления указанным массивом, а также несколькими перегруженными операторами.

Причины использования char * по std::string:

C backwards-compatibility.
Performance (potentially).
char*s have lower-level access.

Причины использования std::string над char *:

Much more intuitive to use.
Better searching, replacement, and manipulation functions.
Reduced risk of segmentation faults.

Пример:

char * должен использоваться в сочетании с массивом char или с динамически распределенным массивом char. В конце концов, указатель бесполезен, если он фактически не указывает на что-то. Это в основном используется в программах на C:

char somebuffer[100] = "a string";
char* ptr = somebuffer;  // ptr now points to somebuffer
cout << ptr; // prints "a string"
somebuffer[0] = 'b';  // change somebuffer
cout << ptr;  // prints "b string" 

обратите внимание, что при изменении "somebuffer" также изменяется "ptr". Это потому, что в этом случае somebuffer является фактической строкой. ptr просто указывает/ссылается на него.

С std::string это менее странно:

std::string a = "a string";
std::string b = a;
cout << b;  // prints "a string"
a[0] = 'b';  // change 'a'
cout << b;  // prints "a string" (not "b string") 

Здесь вы можете видеть, что изменение "a" не влияет на "b", потому что "b" - это настоящая строка.

Но на самом деле главное отличие заключается в том, что с массивами char вы отвечаете за управление памятью, тогда как std::string делает это за вас. В С++ существует очень мало причин использовать массивы char по строкам. 99 раз из 100 вам лучше со строкой.

Пока вы полностью не поймете управление памятью и указатели, просто сохраните себе некоторые головные боли и используйте std::string.

Ответ 5

Зачем использовать std::string над строками c-style в С++?

Основная причина заключается в том, что он освобождает вас от управления временем жизни строковых данных. Вы можете просто рассматривать строки как значения и позволить компилятору/библиотеке беспокоиться об управлении памятью.

Ручное управление распределением памяти и временем жизни является утомительным и подверженным ошибкам.

Каковы недостатки (если таковые имеются) практики, упомянутой в № 1?

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

Если вы не будете осторожны, вы можете получить много ненужных копий данных (в нерекомментированной реализации) или манипуляции счетным счетом (в обновленной версии)

В проекте на смешанном языке любая функция, аргументы которой используются std::string или любая структура данных, содержащая std::string, не будет использоваться напрямую с других языков.

Каковы сценарии, где противоположность рекомендаций, упомянутых в № 1, является хорошей практикой?

У разных людей будут разные мнения по этому поводу, но IMO

  • Для аргументов функции передача строк в "const char *" является хорошим выбором, поскольку она позволяет избежать unessacery copy/refcouning и дает гибкость вызывающего абонента в том, что они передают.
  • Для вещей, используемых при взаимодействии с другими языками, у вас мало выбора, кроме как использовать строки c-style.
  • Если у вас есть ограничение на длину, возможно, быстрее использовать массивы фиксированного размера.
  • При работе с очень длинными строками может быть лучше использовать конструкцию, которая будет определенно скопирована, а не скопирована (например, массив символов, завернутый в shared_ptr), или вообще использовать совсем другой тип структуры данных.

Ответ 6

В общем, вы всегда должны использовать std::string, так как он менее подвержен ошибкам. Помните, что накладные расходы памяти std::string значительны. Недавно я провел несколько экспериментов над служебными данными std::string. В общем, это около 48 байт! Статья находится здесь: http://jovislab.com/blog/?p=76.