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
.