char * vs std :: string в c ++ [закрыто]

DirectX? В основном смесь C и C ++

OpenGL? Английский, потому что сам OpenGL - это просто документ спецификации, написанный в технической прозе. Большинство реализаций OpenGL также написаны на смеси C и C ++.

79
задан jww 8 February 2015 в 21:23
поделиться

12 ответов

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

Я использую std :: string / wstring для более или менее всего, что является настоящим текстом. char * полезна для других типов данных, и вы можете быть уверены, что они освобождаются, как и должны. В противном случае std :: vector - путь.

Вероятно, есть исключения из всего этого.

55
ответ дан 24 November 2019 в 10:13
поделиться

Использование необработанных строк

Да, иногда вы действительно можете это сделать. При использовании const char *, массивов char, размещенных в стеке, и строковых литералов вы можете сделать это таким образом, чтобы вообще не выделять память.

При написании такого кода часто требуется больше внимания и заботы, чем при использовании строки или вектора, но с правильными методами это может быть сделано. При правильных методах код может быть безопасным, но вы всегда должны быть уверены, что при копировании в char [] у вас либо есть некоторые гарантии на длину копируемой строки, либо вы проверяете и обрабатываете слишком длинные строки изящно. В противном случае семейство функций strcpy приобрело репутацию небезопасного.

Как шаблоны могут помочь в написании безопасных буферов char

Что касается безопасности буферов char [], шаблоны могут помочь, поскольку они могут создать инкапсуляцию для обработки размера буфера для вас. Подобные шаблоны реализованы, например, Microsoft, чтобы обеспечить безопасную замену strcpy. Приведенный здесь пример извлечен из моего собственного кода, в реальном коде гораздо больше методов, но этого должно быть достаточно, чтобы передать основную идею:

template <int Size>
class BString
{
  char _data[Size];

  public:
  BString()
  {
    _data[0]=0;
    // note: last character will always stay zero
    // if not, overflow occurred
    // all constructors should contain last element initialization
    // so that it can be verified during destruction
    _data[Size-1]=0;
  }
  const BString &operator = (const char *src)
  {
    strncpy(_data,src,Size-1);
    return *this;
  }

  operator const char *() const {return _data;}
};

//! overloads that make conversion of C code easier 
template <int Size>
inline const BString<Size> & strcpy(BString<Size> &dst, const char *src)
{
  return dst = src;
}
13
ответ дан 24 November 2019 в 10:13
поделиться

Моя точка зрения такова:

  • Никогда не используйте char *, если вы не вызываете код "C".
  • Всегда используйте std :: string: это проще, это удобнее , оно оптимизировано, это стандартно, оно предотвратит появление ошибок, оно было проверено и доказано, что оно работает.
55
ответ дан 24 November 2019 в 10:13
поделиться

Один из случаев, когда вы ДОЛЖНЫ использовать char * , а не std :: string , - это когда вам нужны статические строковые константы. Причина этого в том, что вы не имеете никакого контроля над модулями заказа, инициализирующими свои статические переменные, и другой глобальный объект из другого модуля может ссылаться на вашу строку до ее инициализации. http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Static_and_Global_Variables

std :: string pros:

  • управляет памятью для вас (строка может расти, и реализация выделит вам больший буфер)
  • Интерфейс программирования более высокого уровня, прекрасно работает с остальными из STL.

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

9
ответ дан 24 November 2019 в 10:13
поделиться

Следует рассмотреть возможность использования char * в следующих случаях:

  • Этот массив будет передан в параметре.
  • Вы заранее знаете максимальный размер ваш массив (вы знаете это, ИЛИ вы навязываете его).
  • Вы не будете делать никаких преобразований для этого массива.

На самом деле, в C ++ char * часто используются для фиксированного маленького слова, так как параметры, имя файла и т. д.

8
ответ дан 24 November 2019 в 10:13
поделиться

Даже когда производительность имеет решающее значение, лучше использовать vector - это позволяет заранее выделить память (метод Reserve ()) и поможет избежать утечек памяти. Использование vector :: operator [] приводит к накладным расходам, но вы всегда можете извлечь адрес буфера и проиндексировать его точно так же, как если бы это был символ *.

1
ответ дан 24 November 2019 в 10:13
поделиться

AFAIK внутренне большинство std :: string реализует копию при записи, семантику с подсчетом ссылок, чтобы избежать накладных расходов, даже если строки не передаются по ссылке.

-1
ответ дан 24 November 2019 в 10:13
поделиться

Если вы хотите использовать библиотеки C, вам придется иметь дело с C-строками. То же самое относится, если вы хотите представить свой API для C.

2
ответ дан 24 November 2019 в 10:13
поделиться

, если вы используете массив символов в подобном тексте и т. Д., Используйте std :: string более гибким и простым в использовании. Если вы используете его для чего-то еще, например, для хранения данных? используйте массивы (предпочитайте векторы)

1
ответ дан 24 November 2019 в 10:13
поделиться

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

Стоит также отметить, что std: : итераторы строк довольно часто отображаются на указатели на основной массив символов. Таким образом, любой алгоритм, который вы разрабатываете на основе итераторов, по сути идентичен тому же алгоритму на вершине char * с точки зрения производительности.

operator [] - большинство реализаций STL не выполняют проверку границ и должны преобразовывать это в ту же операцию в базовом массиве символов. AFAIK STLPort может дополнительно выполнять проверку границ, после чего этот оператор будет работать немного медленнее.

Так что же дает вам использование std :: string? Это освобождает вас от ручного управления памятью; изменение размера массива становится проще, и вам, как правило, приходится меньше думать об освобождении памяти.

Если вы беспокоитесь о производительности при изменении размера строки, есть функция резерв , которая может оказаться полезной.

в этот момент этот оператор будет немного медленнее.

Так что же дает вам использование std :: string? Это освобождает вас от ручного управления памятью; изменение размера массива становится проще, и вам, как правило, приходится меньше думать об освобождении памяти.

Если вы беспокоитесь о производительности при изменении размера строки, есть функция резерв , которая может оказаться полезной.

в этот момент этот оператор будет немного медленнее.

Так что же дает вам использование std :: string? Это освобождает вас от ручного управления памятью; изменение размера массива становится проще, и вам, как правило, приходится меньше думать об освобождении памяти.

Если вы беспокоитесь о производительности при изменении размера строки, есть функция резерв , которая может оказаться полезной.

2
ответ дан 24 November 2019 в 10:13
поделиться

JSON обычно намного меньше, чем его XML-эквивалент. Меньшая передача означает более быструю передачу, что приводит к улучшению взаимодействия с пользователем.

5
ответ дан 24 November 2019 в 10:13
поделиться

Use (const) char* as parameters if you are writing a library. std::string implementations differ between different compilers.

3
ответ дан 24 November 2019 в 10:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: