Главная » Просмотр файлов » Б. Страуструп - Дизайн и Эволюция C++. 2006

Б. Страуструп - Дизайн и Эволюция C++. 2006 (1160775), страница 89

Файл №1160775 Б. Страуструп - Дизайн и Эволюция C++. 2006 (Б. Страуструп - Дизайн и Эволюция C++. 2006) 89 страницаБ. Страуструп - Дизайн и Эволюция C++. 2006 (1160775) страница 892019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

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

Итак, критерий сортировки не встраивается ни в контейнер, ни в тип элемента. Вместо этого он передается в виде операции, которую следует выполнить. Если в качестве примера взять строки, состоящие из слов — личных шведских имен, тогда какую схему упорядочения применить для сравнения? Для шведского языка обычно применяются две разные схемы. Но нет сомнения, что нельзя давать сведения о соглашениях, принятых для такой операции, ни общему типу строки, ни общему алгоритму сортировки. Таким образом, любое общее решение включает выраженный в общих терминах алгоритм сортировки, который можно определить не для конкретного типа, а лля конкретного использования данного типа.

Давайте, например, обобщим стандартную библиотечную функцию в сгсшр ( ) для работы со строками любого типа т. Сначала определяется шаблон класса с семантикой сравнения объекта типа т по умолчанию: Гетр1асе<с1авв Т> с1авв СИР ( рпЫ!с: вгагйс !пг ес((т а, т ы ( гегагп а==ь; ) всаг1с 1пс 1С(Т а, Т Ы ( гегцгп а<Ь; ) ); Здесь необходимо использовать шаблон, поскольку мы проеюируем контейнер. Наследование от класса Сопгаьпег необходимо, чтобы Сопггошей сопга1пег можно было использовать в качестве контейнера.

Использование ар~умента шаблона л позволяет применять различные распределители. Например: ~ИИИИИИВ Шаблоны В шаблоне функции сотраге ( ] для сравнения аргументов типа Ьаяфс всгфпд используется такая форма: тевр1ате,<с1аяя Т> а1аяя Ьаятс ятттпд ( // ); тевр1атесс1аяя т, с1аяя С = СМР<Т» тпт совраге(аопят Ьав'с ятг1пд<т>й ятг1, сопят Ьая[а втт1пд<Т>й яаг2] ( сот(1пт 1=0; 1<ятт1.1епдтЬ() йй 1<втт2.1епдтп(); 1++) 1й (!С::ес)(втт1[т),ятг2[1))) тетптп С::1т(яат1[1],ятт2[1]); тетптп втт2. 1епдтп()-ятг1.1еадтЬ(); ) ауредет ьаяйс яаг[пд<аьат> ятттпд; Имея в своем распоряжении шаблоны-члены (см.

раздел 15.9.3), функцию совраге ( ) можно было бы определить и в виде члена класса ьавтс всгтпд. Если требуется, чтобы С<т> производил сравнение без учета регистра, по с учетом специфики конкретного языка, возвращал наибольшее значение в коде па[со([е, когда аргументы неравны (имеется в виду с<т>:: ес) ( ) ) и т.д., то нужно лишь правильным способом определить С<Т>:: ед() и С<Т>:: 1С (] через характерные для типа т операторы. Тогда любой алгоритм (сравнения, сортировки и т.п.) можно выразить в терминах операций, предоставляемых классом Сир и контейнером.

Например: а1аяя Ь1ТЕВАТЕ ятаттс [пт ед(адат а, аьат Ы ( теаитп а==Ь; ) ятаттс [пт 1т(спаг,апат); // использовать книжный порядок чо1б 1(ятт1пд яиеде1, ятг1пд яиеде2) ( соврете(яме<]е1,яиебе2)/ // обычный (телефонный) порядок совраге<спат,ЫТЕЕАТЕ>(яиеде1,яиебе2); // книжный порядок ] чо16 т (ятт1пд я1, ятттпд я2) совраге(я1,я2); аоврате<спаг,НОСАЯЕ>(я1,в2); ] // а учетом регистра // без учета региатра Я передаю критерий сравнения в виде параметра шаблона, поскольку именно так можно передать операции без лишних затрат во время выполнения. В частности, операторы сравнения ес[() и 1г () легко встроить. Аргумент по умолчанию используется, чтобы не обременять пользователей громоздкой нотацией.

Другие варианты этой техники рассматриваются в [2п([, 98А]. Более характерный пример — это сравнение с учетом и без учета регистра: Соотношения между шаблонами классов ДфффЯЯЯЩ Отметим, что шаблон класса смр никогда не используется для определения объектов; все его члены статические и открытые. Поэтому его следовало бы сделать пространством имен (см. главу 17); Сепр1апе<с1аяв Т> паяаврасе СМР ( гпс е!((т а, т ь) ( геспгп а==ь; ) гпс 1с(т а, т Ь) ( гаспгп а<Ь; ) ) К сожалению, шаблоны-пространства имен (пока еще) не включены в С++. 15.9. Соотношения между шаблонами классов Шаблон стоит рассматривать как спецификацию для создания конкретных типов. Другими словами, реализация шаблона — это механизм генерирования типов, указанных пользователем.

Согласно правилам языка С++ два класса, сгенерированные из одного и того же шаблона, никак не связаны между собой. Например: севр1асе<с1аяв т> с1авв Бес ( /* ... */ с1авя БЬаре ( /* ... *! ); с1аяв Сггс1е : риьтгс Бпаре ( /* ... */ ); Видя подобные объявления, пользователи зачастую трактуют Яеп<С1гс1е> как класс, производный от яес<БЬаре>, или яес<сггс1е*> — как производный от Яес<ЯЬаре*>. Например: воЫ Г(Бев<БЬаре>а); ясгс д(зес<Сгпс1еа в) ( Й(я) ! ) Этот пример не будет компилироваться, поскольку не существует встроенного преобразования из Бес<с(гс1е>а в яес<БЬаре>а.

Да и не должно его быть; полагать, что яес<с(гс1е> — частный случай Бес<я)таре>, — принципиальная (и не такая уж редкая) концептуальная ошибка. В частности, класс Бее<С(гс1е> гарантирует, что все его элементы принадлежат С(гс1е (окружность), и значит, пользователи могут безопасно и эффективно применять к ним все операции, определенные для окружностей, например запрашивать значение радиуса. Если бы мы разрешили трактовать Яес<сйгс1е> как Бес<Я)таре>, то уже не могли бы дать такой гарантии, поскольку в множество Бес< БЬаре> можно поместить и другие геометрические фигуры, например, треугольники.

15.9Л. Отношения наследования Следовательно, по умолчанию между классами, сгенерированными из одного и того же шаблона, не может быть никаких отношений. Но иногда такое отношение полезно, Нужна ли специальная операция для выражения такого рода отношений7 Шаблоны НИИИИИВФ Я отверг эту идею, поскольку многие полезные преобразования можно выразить с помощью отношений наследования или обычных операторов-конверторов. Однако в результате ие существует способа выразить некоторые отношения.

Например, располагая Генр1асе<с1аяя Т> с1авя Рлг ( // указатель на Т // ); часто хотелось бы для таких определенных пользователем указателей Рсг иметь такие же отношения наследования, к которым мы привыкли при работе со встроенными указателями. Например: уоЫ б(РГг<сьгс1е> рс) ( Рсг<вларе> рв = рс; // имеет ли зто смысл? ) Желательно, чтобы это было разрешено только тогда, когда я)заре действительно является непосредственным или косвенным открытым базовым классом для С1гс1е.

Дэвид Джордан (РауЫ,) огг(ап) от имени консорциума поставщиков объектно-ориентированных баз данных просил комитет по стандартизации обеспечить такое свойство для «умных» указателей. Решение дают шаблоны-члены, которые пока ие включены в С++: Генр1асе<с1авя т1> с1авв Рлг (// указатель на Т1 // генр1аге<с1аяя т2> орегагог Ргг<т2> (); Нам нужно определить конвертор таким образом, чтобы преобразование Ркг<Т1> в Рбг<Т2 > было допустимо только в случаях, когда т1* можно присвоить т2 *. Это можно сделать, предоставив для Рсг дополнительный конструктор: Геир1асе<с1авв Т> с1авв Рсг ( // указатель на Т т* р; ри)>1(с: Ргг(т*)/ Геир1асе<с1аяв Т2> орегалог Рсг<Т2> (); гегигл Ргг<т2>(р); // работает только тогда, когда // р можно преобразовать в т2* ) // ); В этом решении ие используются приведения типов.

Предложение гесигп будет компилироваться, только когда р может являться аргументом для конструктора Рсг<т2 >. В приведенном примере р имеет тип т1*, а конструктору необходим аргумент типа Т2*. Это применение метода ограничения через использование (см. раздел 15.4.2).

Если вы предпочитаете иметь закрытый конструктор, то можете воспользоваться приемом, предложенным Джонатаном Шопиро: Соотношения между шаблонами классов Яфффф$ЯЯЩ Сепр1асе<с1авв Т> с1авя Рог ( // указатель на Т т* гр; Рог(Т*); ггтепб гепр1аге<с1авв т2> с1авв Ргг<т2>; роЫТс: гепр1аге<с1авв т2> орегагог Ргг<т2> (); // )' Шаблоны-члены описаны в разделе 15.9.3. 15.9.2. Преобразования С вышеописанной проблемой тесно связана другая: не существует единого способа определить преобразования между различными классами, сгенерированными из одного и того же шаблона. Рассмотрим, например, шаблон сопр1ех, который определяет комплексные числа для некоторого множества скалярных типов: Гепр1асе<с1авв вса1аг> с1авв сопр1ех ( вса1аг ге, Тп; роЫтс: // ); Мы можем использовать сопр1ех<й1оас>, сопр1ех<с(ои)21е> и т д., но при этом желательно, чтобы существовало преобразовывание из типа сопр1ех с низкой точностью в тип сопр1ех с высокой точностью.

Например: сопр1ех«)ооЫе> вс)гг (сопр1ех<дооЫе>); сопр1ех<11оас> с1(1.2г,б.тг); сопр1ех<дооЫе> с2 = вцгг(с1);// ошибка: несоответствие типов: // ожидается сопр1ех<доиЫе> Было бы неплохо, если бы сушествовал какой-то способ сделать вызов вс(гс допустимым. Для этого программисты отказываются от шаблонов в пользу дублирования определения классов: с1авв г1оас сопр1ех ( г1оас ге, 1п; роЫто: // ): с1авв бооЫе сопр1ех ( бооЫе ге, 1п; роЫ1с: дооЫе сопр1ех(г1оас сопр1ех с) : ге(с.ге), тп(с.тп) () // ): Цель такого дублирования — определить конструктор, который и задает преобразование. Шаблоны ПИИИИИВ И в этом случае, иа мой взгляд, возможны только решения, требующие вложеииых шаблонов в сочетании с той или иной формой ограничений.

Фактически ограничение может быть иеявиым: Севр1асе<с1авв вса1ас> с1авв совр1ех яса1аг ге, 1п1 риь1!с: Сепр1аСе<с1авв Т2> совр1ех(сопвС совр1ех<Т2>а с) се(с.се), (в(с.1в) ( ) // ): Другими словами, скоиструировать совр1ех<Т1> из совр1ех<Т2> удается только в том случае, когда есть возможность инициализировать т1 с помощью Т2. Это представляется разумным. Такое определение включает и обычный копирующий конструктор.

В данной ситуации приведенный выше пример с яс(гс ( ) становится законным. К сожалению, определение допускает и сужающие преобразования комплексных чисел просто потому, что в С++ допустимы сужающие преобразования для скаляров. Естественно, если принять такое определение совр1ех, то компилятор, предупреждающий о сужаюших преобразованиях для скаляров, будет предупреждать и о сужаюших преобразованиях для значений типа совр1ех. Мы можем получить <привычиые> имена с помощью Суре<1ес: сурес(ет совр1ех<11оаС> 11оас совр1ех; Суреает совр1ех<аооЬ1е> аоивте совр1ех; Суреаес совр1ех<1опд с(ооЬ1е> 1опд аооЬ1е совр1ех; Думается, что варианты без суре<(ей читаются лучше.

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

Тип файла
DJVU-файл
Размер
2,78 Mb
Тип материала
Высшее учебное заведение

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

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