Читать «C++: базовый курс» онлайн - страница 321
Herbert Schildt
Прежде чем рассматривать класс string, важно понять, почему он является частью С++-библиотеки. Стандартные классы не сразу были добавлены в определение языка C++. На самом деле каждому нововведению предшествовали серьезные дискуссии и жаркие споры. При том, что C++ уже содержит поддержку строк в виде массивов с завершающим нулем, включение класса string в C++, на первый взгляд, может показаться исключением из этого правила. Но это далеко не так. И вот почему: строки с завершающим нулем нельзя обрабатывать стандартными С++-операторами, и их нельзя использовать в обычных С++-выражениях. Рассмотрим, например, следующий фрагмент кода.
char s1 [80], s2[80], s3[80];
s1 = "один"; // так делать нельзя
s2 = "два"; // так делать нельзя
s3 = s1 + s2; // ошибка
Как отмечено в комментариях, в C++ невозможно использовать оператор присваивания для придания символьному массиву нового значения (за исключением инструкции инициализации), а также нельзя применять оператор "+" для конкатенации двух строк. Эти операции можно выполнить с помощью библиотечных функций.
strcpy(s1, "one");
strcpy(s2, "two");
strcpy(s3, s1);
strcat(s3, s2);
Поскольку символьный массив с завершающим нулем формально не является самостоятельным типом данных, к нему нельзя применить С++-операторы. Это лишает "изящества" даже самые элементарные операции со строками. И именно неспособность обрабатывать строки с завершающим нулем с помощью стандартных С++-операторов привела к разработке стандартного строкового класса. Вспомните: создавая класс в C++, мы определяем новый тип данных, который можно полностью интегрировать в С++-среду. Это, конечно же, означает, что для нового класса можно перегружать операторы. Следовательно, вводя в язык стандартный строковый класс, мы создаем возможность для обработки строк так же, как и данных любого другого типа, а именно посредством операторов.
Однако существует еще одна причина, оправдывающая создание стандартного класса string: безопасность. Руками неопытного или неосторожного программиста очень легко обеспечить выход за границы массива, который содержит строку с завершающим нулем. Рассмотрим, например, стандартную функцию копирования strcpy(). Эта функция не предусматривает механизм проверки факта нарушения границ массива-приемника. Если исходный массив содержит больше символов, чем может принять массив-приемник, то в результате этой ошибки очень вероятен полный отказ системы. Как будет показано ниже, стандартный класс string не допускает возникновения подобных ошибок.
Итак, существует три причины для включения в C++ стандартного класса string: непротиворечивость данных (строка теперь определяется самостоятельным типом данных), удобство (программист может использовать стандартные С++-операторы) и безопасность (границы массивов отныне не будут нарушаться). Следует иметь в виду, что все выше перечисленное не означает, что вы должны отказываться от использования обычных строк с завершающим нулем. Они по-прежнему остаются самым эффективным средством реализации строк. Но если скорость не является для вас определяющим фактором, использование нового класса string даст вам доступ к безопасному и полностью интегрированному способу обработки строк.