2009-09-23 1 views
44

Мне любопытно узнать, как реализована реализация std :: string и как она отличается от c string? Если стандарт не указывает какую-либо реализацию, то любая реализация с объяснением была бы великолепна в том, как она удовлетворяет требованию строки, заданному стандартом?Как реализована реализация std :: string?

+10

Возможно, вы захотите получить исходный код примерно на gcc и посмотреть, как они его реализуют. –

+1

Связанный: http://stackoverflow.com/questions/3170295/where-can-i-find-the-implementation-for-stdstring – 2012-11-15 23:03:32

ответ

68

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

Scott Meyer's book, Effective STL имеет главу о реализациях std :: string, которая является достойным обзором общих вариантов: «Пункт 15: Имейте в виду изменения в версиях string».

Он говорит о 4 варианте:

  • нескольких вариаций на реф подсчета реализации (обычно известной как копирование при записи) - когда объект строки копируется без изменений, RefCount увеличивается на единицу, но реальная строку данных нет. Оба объекта указывают на одни и те же refcounted данные, пока один из объектов не изменяет его, вызывая «копирование при записи» данных. Существуют вариации, в которых хранятся вещи, такие как refcount, locks и т. Д.

  • «Оптимизация коротких строк» ​​(SSO). В этом варианте объект содержит обычный указатель на данные, длину, размер динамически распределенного буфера и т. Д. Но если строка достаточно короткая, она будет использовать эту область для хранения строки вместо динамического выделения буфера

Кроме того, Herb Sutter's "More Exceptional C++" имеет приложение (Приложение A: «Оптимизации, которые не являются (в многопоточном мире)»), в котором обсуждается, почему копирование при записи refcounted реализаций часто приводит к проблемам с производительностью в многопоточных приложениях из-за проблем с синхронизацией.Эта статья также доступна в Интернете (но я не уверен, что точно так же, как то, что в книге):

Обе эти главы стоило бы читать.

+2

Примечание (поскольку связано с недавним вопросом): Интересно, что копирование на реализацию записи выполняет GCC работает лучше, чем оптимизация коротких строк VC++ в ситуациях * move *, потому что операции * move * в первую очередь затрагиваются объектом 'sizeof'. –

+0

«Оптимизация коротких строк», по-видимому, часто сокращается как «SSO»: http: // stackoverflow.com/questions/10315041/Значение-acronym-sso – Raedwald

+0

Я согласен с тем, что книги Скотта Мейерса и Херба Саттера содержат большую общую информацию о строковых реализациях, но они не говорят точно, какие реализации используют какие оптимизации (или неоптимализации). Если вы хотите это знать, здесь есть сравнение: [http://info.prelert.com/blog/cpp-stdstring-implementations](http://info.prelert.com/blog/cpp-stdstring-implementations) – dmr195

6

Существует пример реализации в an answer on this page.

Кроме того, вы можете посмотреть реализацию gcc, если у вас установлена ​​gcc. If not, you can access their source code via SVN. Большая часть std :: string реализована basic_string, поэтому начните там.

Другим возможным источником информации является Watcom's compiler

11

станд :: строка является классом, который оборачивается вокруг какой-то внутренний буфер и предоставляет методы для манипулирования этого буфера.

Строка в C просто массив символов

Объясняя все нюансы, как станд :: строка работает здесь займет слишком много времени. Возможно, посмотрите на исходный код gcc http://gcc.gnu.org, чтобы посмотреть, как они это делают.

3

Это зависит от стандартной библиотеки, которую вы используете.

STLPort например, это реализация стандартной библиотеки C++, которая реализует, среди прочего, строки.

4

Решение C++ для строк сильно отличается от c-версии. Первое и самое важное отличие заключается в том, что c с использованием решения ASCIIZ std :: string и std :: wstring используют два итератора (указатели) для хранения фактической строки. Основное использование строковых классов обеспечивает динамическое выделенное решение, поэтому в расчете накладных расходов процессора при работе с динамической памятью обработка строк более удобна.

Как вы, наверное, уже знаете, C не содержит встроенного типичного строкового типа, предоставляет только пару строковых операций через стандартную библиотеку. Одно из основных различий между C и C++, что C++ обеспечивает завернутую функциональность, поэтому его можно рассматривать как поддельный общий тип.

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

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

Я думаю, что есть достаточно плюсы и минусы и побочные:

C++ строка Pros: - Быстрее итерации в некоторых случаях (используя размер определенно, и не нужны данные из памяти, чтобы проверить, если вы находитесь в конце строки, сравнивая два указателя, которые могут повлиять на кеширование) - Операция буфера заполнена функциональностью строки, поэтому меньше забот о проблемах с буфером.

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