22.2 – Создание и уничтожение std::string
В этом уроке мы рассмотрим, как создавать объекты std::string, а также как создавать строки из чисел и наоборот.
Создание строки
Строковые классы имеют ряд конструкторов, которые можно использовать для создания строк. Здесь мы рассмотрим каждого из них.
Примечание: string::size_type преобразуется в size_t, который является тем же целочисленным типом без знака, который возвращается оператором sizeof. Его фактический размер зависит от среды. Для целей этого руководства представьте его как unsigned int.
string::string()
Конструктор по умолчанию. Создает пустую строку.
Пример кода:
std::string sSource;
std::cout << sSource;
Вывод:
string::string(const string& strString)
Конструктор копирования. Этот конструктор создает новую строку как копию strString.
Пример кода:
std::string sSource{ "my string" };
std::string sOutput{ sSource };
std::cout << sOutput;
Вывод:
my string
string::string(const string& strString, size_type unIndex)
string::string(const string& strString, size_type unIndex, size_type unLength)
string::string(const string& strString, size_type unIndex, size_type unLength)
Этот конструктор создает новую строку, содержащую не более unLength символов из strString, начиная с индекса unIndex.
- Если встречается
NULL, копирование строки завершится, даже если значениеunLengthне было достигнуто. - Если значение
unLengthне указано, будут использоваться все символы, начиная сunIndex. - Если значение
unIndexбольше размера строки, будет выброшено исключениеout_of_range.
Пример кода:
std::string sSource{ "my string" };
std::string sOutput{ sSource, 3 };
std::cout << sOutput<< '\n';
std::string sOutput2(sSource, 3, 4);
std::cout << sOutput2 << '\n';
Вывод:
string
stri
string::string(const char *szCString)
Этот конструктор создает новую строку из строки szCString в стиле C, но не включая завершающий ноль.
- Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение
length_error. - Предупреждение:
szCStringне должна быть равнаnullptr.
Пример кода:
const char *szSource{ "my string" };
std::string sOutput{ szSource };
std::cout << sOutput << '\n';
Вывод:
my string
string::string(const char *szCString, size_type unLength)
Этот конструктор создает новую строку из первых unLength символов из строки szCString в стиле C.
- Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение
length_error. - Предупреждение: только для этой функции нули в
szCStringне обрабатываются как символы конца строки! Это означает, что можно выйти за конец строки, если значениеunLengthслишком велико. Будьте осторожны, чтобы не переполнить строковый буфер!
Пример кода:
const char *szSource{ "my string" };
std::string sOutput(szSource, 4);
std::cout << sOutput << '\n';
Вывод:
my s
string::string(size_type nNum, char chChar)
Этот конструктор создает новую строку, инициализированную nNum вхождениями символа chChar.
- Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение
length_error.
Пример кода:
std::string sOutput(4, 'Q');
cout << sOutput << endl;
Вывод:
QQQQ
template string::string(InputIterator itBeg, InputIterator itEnd)
Этот конструктор создает новую строку, инициализированную символами диапазона [itBeg, itEnd).
- Если результирующий размер превышает максимальную длину строки, будет сгенерировано исключение
length_error.
Здесь нет примера, поскольку это достаточно запутанный способ создания строки, и вы вряд ли когда-то им не воспользуетесь.
Уничтожение строки
string::~string()
Деструктор. Он уничтожает строку и освобождает память.
Здесь также нет примера кода, поскольку деструктор не вызывается явно.
Создание строк из чисел
Одним из заметных упущений в классе std::string является отсутствие возможности создавать строки из чисел. Например:
std::string sFour{ 4 };
выдает следующую ошибку:
c:vcprojectstest2test2test.cpp(10) : error C2664: 'std::basic_string<_Elem,_Traits,_Ax>::basic_string(std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it)' : cannot convert parameter 1 from 'int' to 'std::basic_string<_Elem,_Traits,_Ax>::_Has_debug_it'
Помните, что я сказал о строковых классах, вызывающих страшно выглядящие сообщения об ошибках? Важная информация в сообщении находится здесь:
cannot convert parameter 1 from 'int' to 'std::basic_string
Другими словами, компилятор пытался преобразовать ваш int в строку, но потерпел неудачу.
Самый простой способ преобразовать числа в строки – задействовать класс std::ostringstream. std::ostringstream уже настроен для приема входных данных из различных источников, включая символы, числа, строки и т.д. Он также может выводить строки (либо с помощью оператора извлечения >>, либо с помощью функции str()) . Дополнительные сведения об std::ostringstream смотрите в разделе «23.4 – Классы потоков для строк».
Вот простое решение для создания std::string из различных типов входных данных:
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
inline std::string toString(T tX)
{
std::ostringstream oStream;
oStream << tX;
return oStream.str();
}
Вот пример кода для его проверки:
int main()
{
std::string sFour{ toString(4) };
std::string sSixPointSeven{ toString(6.7) };
std::string sA{ toString('A') };
std::cout << sFour << '\n';
std::cout << sSixPointSeven << '\n';
std::cout << sA << '\n';
}
И вывод:
4
6.7
A
Обратите внимание, что в этом решении не выполняется проверка на ошибки. Возможно, что вставка tX в oStream не удастся. Подходящим решением в случае сбоя преобразования было бы генерирование исключения.
Преобразование строк в числа
Аналогично решению, приведенному выше:
#include <iostream>
#include <sstream>
#include <string>
template <typename T>
inline bool fromString(const std::string& sString, T &tX)
{
std::istringstream iStream(sString);
// извлекаем значение в tX, возвращаем true в случае успеха
return !(iStream >> tX).fail();
}
Вот пример кода для его проверки:
int main()
{
double dX;
if (fromString("3.4", dX))
cout << dX << '\n';
if (fromString("ABC", dX))
cout << dX << '\n';
}
И вывод:
3.4
Обратите внимание, что второе преобразование завершилось неудачей и вернуло false.
