Главная » Просмотр файлов » Б. Страуструп - Язык программирования С++

Б. Страуструп - Язык программирования С++ (1119446), страница 55

Файл №1119446 Б. Страуструп - Язык программирования С++ (Б. Страуструп - Язык программирования С++) 55 страницаБ. Страуструп - Язык программирования С++ (1119446) страница 552019-05-09СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 55)

Примеры использования операций ++ и -- дляитераций можно найти в $$8.8.197Бьерн Страуструп.Язык программирования С++7.11 Строковый классТеперь можно привести более осмысленный вариант класса string. В нем подсчитывается число ссылокна строку, чтобы минимизировать копирование, и используются как константы стандартные строки C++.#include <iostream.h>#include <string.h>class string {struct srep {char* s;// указатель на строкуint n;// счетчик числа ссылокsrep() { n = 1; }};srep *p;public:string(const char *);// string x = "abc"string();// string x;string(const string &);// string x = string ...string& operator=(const char *);string& operator=(const string &);~string();char& operator[](int i);friend ostream& operator<<(ostream&, const string&);friend istream& operator>>(istream&, string&);friend int operator==(const string &x, const char *s){ return strcmp(x.p->s,s) == 0; }friend int operator==(const string &x, const string &y){ return strcmp(x.p->s,y.p->s) == 0; }friend int operator!=(const string &x, const char *s){ return strcmp(x.p->s,s) != 0; }friend int operator!=(const string &x, const string &y){ return strcmp(x.p->s,y.p->s) != 0; }};Конструкторы и деструкторы тривиальны:string::string(){p = new srep;p->s = 0;}string::string(const string& x){x.p->n++;p = x.p;}string::string(const char* s){p = new srep;p->s = new char[ strlen(s)+1 ];strcpy(p->s, s);}string::~string(){if (--p->n == 0) {delete[] p->s;delete p;}198Бьерн Страуструп.Язык программирования С++}Как и всегда операции присваивания похожи на конструкторы.

В них нужно позаботиться об удалениипервого операнда, задающего левую часть присваивания:string& string::operator=(const char* s){if (p->n > 1) {// отсоединяемся от старой строкиp->n--;p = new srep;}else// освобождаем строку со старым значениемdelete[] p->s;p->s = new char[ strlen(s)+1 ];strcpy(p->s, s);return *this;}string& string::operator=(const string& x){x.p->n++;// защита от случая ``st = st''if (--p->n == 0) {delete[] p->s;delete p}p = x.p;return *this;}Операция вывода показывает как используется счетчик числа ссылок. Она сопровождает как эхокаждую введенную строку (ввод происходит с помощью операции << , приведенной ниже):ostream& operator<<(ostream& s, const string& x){return s << x.p->s << " [" << x.p->n << "]\n";}Операция ввода происходит с помощью стандартной функции ввода символьной строки ($$10.3.1):istream& operator>>(istream& s, string& x){char buf[256];s >> buf;// ненадежно: возможно переполнение buf// правильное решение см.

в $$10.3.1x = buf;cout << "echo: " << x << '\n';return s;}Операция индексации нужна для доступа к отдельным символам. Индекс контролируется:void error(const char* p){cerr << p << '\n';exit(1);}char& string::operator[](int i){if (i<0 || strlen(p->s)<i) error("недопустимое значение индекса");return p->s[i];}199Бьерн Страуструп.Язык программирования С++В основной программе просто даны несколько примеров применения строковых операций. Слова извходного потока читаются в строки, а затем строки печатаются. Это продолжается до тех пор, пока небудет обнаружена строка done, или закончатся строки для записи слов, или закончится входной поток.Затем печатаются все строки в обратном порядке и программа завершается.int main(){string x[100];int n;cout << " здесь начало \n";for ( n = 0; cin>>x[n]; n++) {if (n==100) {error("слишком много слов");return 99;}string y;cout << (y = x[n]);if (y == "done") break;}cout << "теперь мы идем по словам в обратном порядке \n";for (int i=n-1; 0<=i; i--) cout << x[i];return 0;}7.12 Друзья и членыВ заключении можно обсудить, когда при обращении в закрытую часть пользовательского типа стоитиспользовать функции-члены, а когда функции-друзья.

Некоторые функции, например конструкторы,деструкторы и виртуальные функции ($$R.12), обязаны быть членами, но для других есть возможностьвыбора. Поскольку, описывая функцию как член, мы не вводим нового глобального имени, приотсутствии других доводов следует использовать функции-члены.Рассмотрим простой класс X:class X {// ...X(int);int m1();int m2() const;friend int f1(X&);friend int f2(const X&);friend int f3(X);};Вначале укажем, что члены X::m1() и X::m2() можно вызывать только для объектов класса X.Преобразование X(int) не будет применяться к объекту, для которого вызваны X::m1() или X::m2():void g(){1.m1();1.m2();}// ошибка: X(1).m1() не используется// ошибка: X(1).m2() не используетсяГлобальная функция f1() имеет то же свойство ($$4.6.3), поскольку ее параметр - ссылка безспецификации const.

С функциями f2() и f3() ситуация иная:void h(){f1(1);f2(1);f3(1);}// ошибка: f1(X(1)) не используется// нормально: f2(X(1));// нормально: f3(X(1));200Бьерн Страуструп.Язык программирования С++Следовательно операция, изменяющая состояние объекта класса, должна быть членом или глобальнойфункцией с параметром-ссылкой без спецификации const. Операции над основными типами, которыетребуют в качестве операндов адреса (=, *, ++ и т.д.), для пользовательских типов естественноопределять как члены.Обратно, если требуется неявное преобразование типа для всех операндов некоторой операции, тореализующая ее функция должна быть не членом, а глобальной функцией и иметь параметр типассылки со спецификацией const или нессылочный параметр. Так обычно обстоит дело с функциями,реализующими операции, которые для основных типов не требуют адресов в качестве операндов (+, -, ||и т.д.).Если операции преобразования типа не определены, то нет неопровержимых доводов в пользуфункции-члена перед функцией-другом с параметром-ссылкой и наоборот.

Бывает, что программиступросто одна форма записи вызова нравится больше, чем другая. Например, многим для обозначенияфункции обращения матрицы m больше нравится запись inv(m), чем m.inv(). Конечно, если функцияinv() обращает саму матрицу m, а не возвращает новую, обратную m, матрицу, то inv() должна бытьчленом.При всех прочих равных условиях лучше все-таки остановиться на функции-члене. Можно привеститакие доводы.

Нельзя гарантировать, что когда-нибудь не будет определена операция обращения.Нельзя во всех случаях гарантировать, что будущие изменения не повлекут за собой изменения всостоянии объекта. Запись вызова функции-члена ясно показывает программисту, что объект можетбыть изменен, тогда как запись с параметром-ссылкой далеко не столь очевидна. Далее, выражениядопустимые в функции-члене могут быть существенно короче эквивалентных выражений в глобальнойфункции. Глобальная функция должна использовать явно заданные параметры, а в функции-членеможно неявно использовать указатель this.

Наконец, поскольку имена членов не являются глобальнымиименами, они обычно оказываются короче, чем имен глобальных функций.7.13 ПредостереженияКак и всякое другое языковое средство, перегрузка операций может использоваться разумно инеразумно. В частности, возможностью придавать новый смысл обычным операциям можновоспользоваться так, что программа будет совершенно непостижимой. Представьте, каково будетчитателю, если в своей программе вы переопределили операцию + так, чтобы она обозначалавычитание. Описанный здесь механизм перегрузки будет защищать программиста и пользователя оттаких безрассудств.

Поэтому программист не может изменить ни смысл операций над основнымитипами данных, такими, как int, ни синтаксис выражений и приоритеты операций для них.По всей видимости перегрузку операций имеет смысл использовать для подражания традиционномуиспользованию операций. Запись с обычным вызовом функции можно использовать в тех случаях,когда традиционной записи с базовой операцией не существует, или, когда набор операций, которыедопускают перегрузку, не достаточен, чтобы записать с его помощью нужные действия.7.14 Упражнения1.(*2) Определите итератор для класса string.

Определите операцию конкатенации + и операцию += ,значащую "добавить в конец строки". Какие еще операции вы хотели бы и смогли определить дляэтого класса?2.(*1.5) Определите для строкового класса операцию выделения подстроки с помощью перегрузки ().3.(*3) Определите класс string таким образом, чтобы операцию выделения подстроки можно былоприменять к левой части присваивания. Вначале напишите вариант, в котором строку можноприсваивать подстроке той же длины, а затем вариант с различными длинами строк.4.(*2) Разработайте класс string таким образом, чтобы объекты его трактовались при передачепараметров и присваивании как значения, т.е.

чтобы в классе string копировались самипредставления строк, а не только управляющие структуры.5.(*3) Измените класс string из предыдущего упражнения так, чтобы строки копировались только принеобходимости. Это значит, что нужно хранить одно общее представления двух одинаковых строк201Бьерн Страуструп.Язык программирования С++до тех пор, пока одна из них не изменится. Не пытайтесь задать операцию выделения подстроки,которую одновременно можно применять и к левой части присваивания.6.(*4) Определите класс string, обладающий перечисленными в предыдущих упражненияхсвойствами: объекты его трактуются как значения, копирование является отложенным (т.е.происходит только при необходимости) и операцию выделения подстроки можно применять к левойчасти присваивания.7.(*2) Какие преобразования типа используются в выражениях следующей программы?struct X {int i;X(int);operator+(int);};struct Y {int i;Y(X);operator+(X);operator int();};extern X operator*(X,Y);extern int f(X);X x = 1;Y y = x;int i = 2;int main(){i + 10;x + y + i;f(y);}y + 10;x * X +i;y + y;y + 10 * y;f(7);106 + y;Определите X и Y как целые типы.

Измените программу так, чтобы ее можно было выполнить и онанапечатала значения всех правильных выражений.8.(*2) Определите класс INT, который будет эквивалентен типу int. Подсказка: определите функциюINT::operator int().9.(*1) Определите класс RINT, который будет эквивалентен типу int, за исключением того, чтодопустимыми будут только операции: + (унарный и бинарный), - (унарный и бинарный), *, / и %.Подсказка: не надо определять RINT::operator int().10.

Характеристики

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6367
Авторов
на СтудИзбе
310
Средний доход
с одного платного файла
Обучение Подробнее