Г. Шилдт - Полный справочник по C++ (1109478), страница 140
Текст из файла (страница 140)
Зто позволяет выполнять цепочки присваивания. Часть )(. Приложения на языке С++ з з ЯбдТуре х, у, яз х = у .= в = "проверка"; ~~2 Конкатенация Конкатенация двух строк выполняется с помощью оператора "+". Класс лсхтуре предусматривает три вида конказснации. ° Конкатенация объекта класса ясхтуре с другим объектом этого типа ° Конкатенация объекта класса яехтуре со строкой, взятой в кавычки. ° Конкатенация строки, взятой в кавычки, с объектом класса ясктуре. В каждом из этих вариантов оператор "+'* возвращает объект класса лехтуре, являющийся конкатенацией двух операндов. Ни один из этих операндов нс мслифицируетсл. рассмотрим перегруженную операторную Функцию орехасол+(). // Конкатенация двух объектов класса Яехтуре.
ятстуре ягдтурез:орехасох+(ясгтуре ао) ( зпе 1епз Яегтуре Сетрз бЕ1ЕСе [) ГЕИР.РЗ 1еп = якг1еп(о.р) + ятс1еп(р) + 1," сезар.ягяе = 1еп; сгу Сезар.р = пеи спат[1еп)з саесЬ (Ьаг) а11ос ха) ( соне « "Ошибка при выделении паиятихп"з еххе(1)з яегсру(Сезар.р, Р)з ясгсас(селзр.р, о.р)з гегцхп семр; 3 // Конкатенация объекта класса Яестуре со строкой, // взятой в кавычки. ЯехТуре ЯехТурез:орегаеог+(спад *я) ( 1пс 1епз ЯтхТуре Сеирз С[е1еее [) Сеыр.рз 1еп = ясс1еп(в) + яьг1еп(р) + 1; Селзр.ягзе = 1епз сгу ( Севзр.р = ззеи сЬах[1еп)з ) сабсЬ (Ьас) а11ос ха) ( соцс « "Оыибка при распределении памяти'зп"з ехзс (1); ) Глава 39.
Интырация новых классов: пользовательский класс длв работы со строками 787 всссру(сепр.р, р) встсас(сепр.р, в) сесптп сепр; // Конкатенация строки, взятой а казы ~як, // и объекта класса ЯСгТуре. БГ сТуре орегакос+(сиах *в, Я(стуре Ьо) ( ъпс 1еп; БксТуре Сепр; с)е1есе () сепр.р; 1еп = вбс1еп(в) ъ збт1еп(о.р) + 1; сепр.втсе = 1еп; ссу ( сепр.р = псы сиах(1еп); ) сабсЬ (Ьаб а11ос ха) ( сопс « "описка при распределении памяти(п"/ ехТС(1); ) всхсру(гепр.р, в); встсас(гепр.р.
о.р): табака сепр; Все три функции работают приблизительно одинаково. Во-псрвых, создастся временный объект сепр класса всхтура. Этот объскт хранит результат коикатсиации и возвращается функциями в вызывающий модуль. Поскольку явная иии1(иализация временного обьскта ис выполняется, при ого создании вылслястся только 1 байт (для символа-заполнителя). По этой причина память, иа которую ссылается указатель свпр.р, сначала освобождается, а затем функция выделяет область памяти„достаточиую для того, чтобы в исс поместился результат конкатенации двух строк. В заклю ~сиис, две строки копируются в область памяти, адресуемую указателем свпр р, и объект сепр возвращается в вызывающий модуль. Вычитание подстроки В классе ьав1с всккпо ис предусмотрена заюя полсзивя функция, как вычита//ис лодс/проки.
В соответствии со своим опрсдслсиисм в классе всктурв, эта опсрация удаляет из объекта все подо~роки, совпадаюшис с указашюй полстрокой. Вычитание подстроки выполняется с помощью оператора "-". Класс всттурв предусматривает два вида вычитания подстроки. Первый вариант позволяет вычитать из объекта класса всктуре другой объскт этого типа. Второй вариант удаляет из объекта класса всхтурв всс вхождения указанной подстроки, взятой в кавычки. Слсдуюший фрагмент программы иллюстрируст оба варианта Т // Вычитание объектов класса БСстуро. ясхтуре Бьстуре::орекасох-(ясхтуре ьвпьвьт) ( Часть )).
Приложения иа языке С++ ЯттТуре Сеязр(р) з сЬах "я1; кпс )., я1 = )зз йот(1=0з *я1; 1++) ( (К(*я1<ь*виЬятт.р) ( Сеир.р[1] = *в1з // Если символ не является первой // буквой подстроки, копируем его //в объект Хемр. в1++ з ) е1яе ( ЕогЦ=Оз яиЬятх.р[5!==я1[З) аа яиЬвтт.р[Э)з ]++) 1х<<яиЬятг.р[])) ( // Если подстрока обнаружена, // удаляем ее. я1 1 †; ) е1яе ( // Если нет, Сежр.р[1) = *я1з я1++з ) ) ) оетр.р[1] = '10' з хеситтз Сеирз прололжаем копирование. // Вычитание ия объекта класса ясхтуре строки, // взятой в кавычки. Яхгтуре ЯхгТуреззорехахох-(сЬаг *виЬяхт) ( яхттуре Хеир(р)з сЬат *в1з Тпс я1 = рз Ест<1=0з *я1; х++) 1Г(*я1!=*виЬвхг) ( // Если символ не является // первой буквой подстроки, сеир.р[1) = *я1; // копируем его в объект сежр.
я1ъ+з е1яе ( Сох<О=Оз яиЬвст[0]==я1[З] аа яиЬягт[])з О++) 1Й(!яиЬятх[з]) ( // Если подстрока обнаружена, // удаляем ее. я1 += зз х— ) е1яе ( // Если нет, продолжаем копирование. Сеир.р[1) = *в1з я1++; ) ) гетр.р[1] = '10'з тетитп Хетрз ) Глава 39. Инзвграцнв новых классов< лольяоватвльсклй класс длв раоаты со строкамн 789 Обе Функции копируют содержимое левого операнда в объект еещр, удаляя любые ахгокдения подстроки, указаннои в правом операнде.
й качестве результата возврашается объект класса веттуре. Ни один из операндов в ходе вычитания нс изменяется. Рассмотрим конкретные примеры вычитания подстрок. Бсхтуре х("11йе С++" ), у("11йе" ); БхгТуре х; х = х — у; // Объект т будет содержать строку " 1 С++". х = х — "С<+"; // Объект т будет содержать строку "1 11)ге // Удаление многократных вхождений подстроки. х = "АВСОАВСО'; х = х -'А"; // Объект х содержит строку "ВСПВСО Операторы сравнения Класс веттуре предусматривает полный набор перегруженных операторов сравнения строк. Оци перечислены в объявлении класса.
Повторим их еше раз. БхтТуре. ( геситп хесигп ( тетитп ( хесигп ( тесигп ( хеситп класса БетТуре н строками, !яххсп1р(р, я): ясгсыр(р, в): р[р, я) < О; ) ясхсыр(р, я) > О; ) яххсыр(р, я) <= О; ) ясхсыр(р, я) >= О; ) Операции сравнения весьма просты, Их реализация не вызывает никаких затруднений. Однако следует помнить, что левым операндом этих операций обязательно должен быть объект класса веттуре.
Если вам понадобится использовать в качестве левого операнда операции сравнения строку, заключенную в кавычки, придется лобавить поные функции. Таким образом, приведенные ниже сравнения строк вполне согласуются с определением класса. БехТуре х("опе"), у("Смо"], х("С)зхее'); 11(х < у) саит « "х меньяе у"; хб(х=="ецгее") саит « "х равно сцгее у = "о"; х = "пе"; 1х[х==(у+х)) саит « "х равно у+х" Часть )(. Прилежания нв языке С++ // Сравнение объектов класса хпс орегахох==(БХгТуре ао) хпх прелатах!=-(Бхгтуре ао) 1пс прелатах<(БСгТуре ао) хпс орехасох>(Бсгтуре ао) 1пх оретасог<=(Бсгтуре ао) хпх орегахох>=(БСгТуре аа) // Операции над объектами // взятыми в кавычки.
1пс прелатах==(спал *я) ( хпс прелатах)=(с)заг *я) ( 1пс орегахог<(снах *я) ( 1пс оретаеот>(спат *я) ( 1пс прелатах<-"(спас *я) ( 1пс орегахог>=(снах *я) ( тесихп геситп тесихп ге(итп гееихт1 хесихп (ясхсыр(р, о.р); ) яххсыр[р, а.р); ) яегсмр(р, о.р) < О; ) ястспр(р о р) > О- ясхсмр(р, а.р) <= О; ) яхгстр(р, о.р) >= О; ) -;."''":-:.""~ Прочие строковые функции В классе всгтуре определены сшс три Функции, предназначенные для более тесной интеграции этого класса со срсдои программирования на языке С++.
К ним относятся Функции всгв1ве(), ща)сеасг() и Функция преобразования типа орегасог с?гак* () . Вот как выглядят их определения. ?пс всгз(ге() ( гесцгп эсг1еп(р); чозд щакевгг(с)эаг *в) ( вггсру(в, срегагог с?гаг *()( гесигп р; ) ) // возвращает размер строки. р)," ) // Создает строку, // взятую в кавычки. // Преобраз в тип сваг *. Первые Функции вполне очевидны. Функция есг1еп() возвращает длину строки, на которую ссылается указатель р. Поскольку длина этой строки может отличаться от значения„хранящегося в поле аэве (напримср, вслслствис присваивания более короткой строки), длина строки вычисляется с помо?цью функции есгвеп().
Функция ща)гевсг() копирует строку, адресуемую указателем р, в символьный массив. Зта функция оказывается полезной, если необходимо превратить объект класса всгтуре в обычную строку. Функция преобразования орегасог с?заг* [) возвращает указатель р, который ссылается на строку, хранящуюся в объекте. Зта функция позволяет использовать объект класса всгтуре везде, где требуется обычная строка, завершавшаяся нулевым байтом. Например, следующий фрагмент является вполне корректным.
Ясгтуре х("Не11о') с?гаг в(20); // Копирование строкового объекта с помощью функции вггсру() вггсру(«, х)г // Автоматическое преобразование в тип спаг *, Преобразование в тип сваг нарушает принцип инкапсуляции, поскольку, если ЙФ функция получает указатель нв строку, онв может модифицировать ее непосредственно, без помощи функций — членов класса всгтура и самою обьсюпв. По этой причине преобразование в тип сваг * следует примвнягпь осггюрожно. Модификацию строки можно предотвратить, заставив функцию преобразования в гнил саак * возвращать кинствнтныи указатель.
В этом случае инкапсуляция нарушена нв будвгп. Читвгаепи месут сами попробовать изменить класс, руководсгпвуясь этими указаниями. 'Ч Полное определение класса 8$гТуре Ниже приведена программа, солсржашая полное определение класса всгтуре. екпс) цс(е «1овсгеащ> Еспс1цде «пеи> Глава 39. Интеграция новых классов: пользовательский класс для работы со строками 74э Напомним, что Функция преобразования выполняется автоматически, если объект является частью выражения, для которого определено зто преобразование.
В данном случае, поскольку прототип функции астору(] сообщает компилятору, что второй аргумент имеет тип сваг *, автоматически выполняется преобразование типа всгтуре в тип с?гаг *, и возврашастся указатель на строку, содержащуюся в объекте х. Затем этот указатель используется функцией всгсру[) для копирования строки в аргумент в. Благодаря Функции преобразования вместо аргумента типа с?заг * в любой функции можно использовать объект класса всгтуре.