Ответ
В C++ эволюционировали несколько способов работы со строками, каждый со своей областью применения.
-
C-строки (Null-terminated strings) Массивы символов типа
char(илиwchar_tдля широких символов), где конец строки обозначается нулевым символом' '. Это наследие языка C.- Плюсы: Универсальность, работа с любым C API.
- Минусы: Сложное ручное управление памятью, риск переполнения буфера, линейный поиск длины (
O(n)).char cstr[] = "Hello"; // Массив из 6 char: 'H','e','l','l','o',' ' const char* ptr = "Literal"; // Указатель на строковый литерал в read-only памяти
-
std::string(иstd::wstring) Класс из Стандартной библиотеки (<string>), который инкапсулирует динамический массив символов. Это основной способ работы со строками в современном C++.- Плюсы: Автоматическое управление памятью (RAII), богатый интерфейс (поиск, конкатенация, модификация), знает свою длину (
O(1)). - Минусы: Небольшие накладные расходы на хранение размера и ёмкости.
#include <string> std::string s1 = "Hello"; std::string s2 = s1 + " World!"; // Конкатенация size_t len = s2.length(); // Длина = 12
- Плюсы: Автоматическое управление памятью (RAII), богатый интерфейс (поиск, конкатенация, модификация), знает свою длину (
-
std::string_view(C++17) Невладеющее, неизменяемое (read-only) представление подстроки. Содержит только указатель на данные и длину. Аналогspanдля строк.- Плюсы: Лёгковесный (размер ~2 указателя), не выделяет память, идеален для передачи строк в функции только для чтения, устраняет ненужные копии.
- Минусы: Не владеет данными, поэтому исходная строка должна переживать
string_view. Нельзя использовать для хранения.#include <string_view> void process(std::string_view sv) { // Принимает и std::string, и C-строку // Чтение sv[0], sv.substr(...) } std::string str = "..."; process(str); // Нет копирования данных строки process("literal"); // Создаётся временный string_view
-
std::basic_stringс пользовательским аллокатором Шаблонный класс, лежащий в основеstd::string(std::basic_string<char>). Позволяет кастомизировать тип символа (char,wchar_t,char16_t,char32_t) и стратегию выделения памяти.using wstring = std::basic_string<wchar_t>; // std::wstring // Пользовательский аллокатор для особых случаев (например, arena-аллокатор) template<typename T> class MyAllocator { /*...*/ }; using CustomString = std::basic_string<char, std::char_traits<char>, MyAllocator<char>>;
Практическое правило: Для владения строковыми данными используйте std::string. Для передачи строк в функции (только для чтения) используйте std::string_view. Для взаимодействия с C-библиотеками иногда необходимы C-строки (метод c_str() у std::string).