12

Вопрос по c++, string – Зачем использовать std :: string над строками в стиле c в C ++?

& quot; Нужно всегда использоватьстанд :: строка над строками в стиле c (char *) & Quot; это совет, который подходит почти для каждого исходного кода, размещенного здесь. Хотя эта рекомендация, без сомнения, хороша, рассматриваемые вопросы не позволяютwhy? аспект совета подробно. Этот вопрос должен служить заполнителем для того же.

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

  1. Why should one use std::string over c-style strings in C++?
  2. What are the disadvantages (if any) of the practice mentioned in #1?
  3. What are the scenarios where the opposite of the advice mentioned in #1 is a good practice?
  • Я сомневаюсь в утверждении о лучшей производительности C строк. Этоdoes иметь меньше памяти, что может быть крайне важно, если у вас много маленьких строк (например, в разборе или биоинформатике, гдеstd::string может быть непомерно).

    от
  • Использование char * дает вам больше контроля над тем, что происходит & quot; позади & quot; сцены, что означает, что вы можете настроить производительность, если вам нужно.

    от
  • It is значительное. С -O2 и без -g G ++ по-прежнему занимает 24 байта для строки байта. Я полагаю, то же самое для Visual Studio.

    от
  • @asanoki: используя мой код наideone.com/ynJhF (выделив 1000000 строк общей длиной 7 502 096 символов), VC ++ 10 выделил 38 712 КБ для символов char * и unique_ptr и выделил 27 428 КБ для строки. (Это экономия 41%). G ++ 4.5.4 выделил 23 052 КБ для символов char * и unique_ptr и выделил 33 832 КБ для строки (это 47% дополнительного пространства).

    от
  • Все зависит от реализации. Но на практике, без отладочных вещей, подслушивание должно быть незначительным.

    от
  • Жаль, что небольшая оптимизация строки - отличная вещь.

    от
  • @KarlKnechtel: Извините, кажется, я новичок в C ++, в отличие от вас :) Однако я бы потрудился прочитать весь вопрос & amp; понимание цели, а не просто чтение заголовка, прежде чем комментировать.

    от Alok Save
  • Это все еще спрашивают в 2012 году ?! Кроме того, когда совет для использованияstd::string Когда-либоnot сопровождается рационализацией?

    от Karl Knechtel
  • Я планирую пометить этоc++-Faq & Амп; обсудим то же самое вC++ Lounge в ближайшее время.

    от Alok Save
6 ответов
  • 13

    Code:

    std::string manages its own memory, so you can copy, create, destroy them easily. You can't use your own buffer as a std::string. You need to pass a c string / buffer to something that expects to take ownership of the buffer - such as a 3rd party C library.

  • 2

    3) советalways использование

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

  • -1

    В общем, вы всегда должны использовать std

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

  • 4

    Ну если тыjust 

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

    Например, определение длины массива символов требует «подсчета» символы в массиве. Напротив, std :: string обеспечивает эффективную операцию для этой конкретной задачи. (увидетьhttps://stackoverflow.com/a/1467497/129622)

    For power, efficiency and sanity Larger memory footprint than "just" a char array When you just need an array of chars

  • 1

    Why should one use std::string over c-style strings in C++?

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

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

    What are the disadvantages (if any) of the practice mentioned in #1?

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

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

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

    What are the scenarios where the opposite of the advice mentioned in #1 is a good practice?

    Разные люди будут иметь разные мнения по этому поводу, но ИМО

    For function arguments passing strings in "const char *" is a good choice since it avoids unnessacery copying/refcouning and gives the caller flexibility about what they pass in. For things used in interoperation with other languages you have little choice but to use c-style strings. When you have a known length limit it may be faster to use fixed-size arrays. When dealing with very long strings it may be better to use a construction that will definately be refcounted rather than copied (such as a character array wrapped in a shared,_ptr) or indeed to use a different type of data structure altogether

  • 1

    Char * - это в основном указатель на символ. То

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

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

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

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

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

    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"; фактическая строка

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

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