Главная » Просмотр файлов » А. Александреску - Современное проектирование на C++

А. Александреску - Современное проектирование на C++ (1119444), страница 72

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

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

Преобразование "указатель на функцию — указатель на функцию" не подходит, поскольку после возврашения из функции гппоиЬ)еп1эратсйег::дбг! информация о статическом типе теряется. и к какому типу следует приводить параметр, неизвестно. (Попробуйте разобрать какой-нибудь код, и вы сразу поймете, в чем дело.) Мы решим задачу динамического приведения типов с помошью простого обратного вызова функций (а не функторов). Таким образом, шаблонный аргумент са11- Ьас!гтеар1ате является указателем на функцию. Решить задачу нам поможет траиплииная фуикция (ггатройпе Гцпсг!оп), также известная под названием саик (гйцп1).

Трамплинные функции — это маленькие функции, выполняюшие небольшую настройку перед вызовами других функций. Обычно они используются разработчиками компиляторов языка С++ для реализации ковариантных типов возврашаемых значений и настройки указателей при множественном наследовании. Мы будем использовать трамплинную функцию, выполняюшую соответствуюшее приведение типов, а затем вызывать функцию с подходяшей сигнатурой, облегчая таким образом работу пользователей.

Однако сушествует одна проблема: объект са11- Ьас!гмар теперь должен хранить два указателя на функции: один предоставляется пользователем, а другой является указателем на трамплинную функцию. Это снижает быстродействие программы. Вместо одного косвенного вызова через указатель у нас есть два. Кроме того, реализация усложняется. Для преодоления этого препятствия воспользуемся следуюшим фактом. Шаблон может получать указатель на функцию в качестве параметра, лишенного типа. (В большинстве книг шаблонные параметры, лишенные типа, представляют собой целочисленные значения.) Вообше говоря, в качестве параметров, лишенных типа, шаблону можно передавать указатели на любые глобальные объекты, в том числе и функции.

При этом должно выполняться единственное условие: функция, адрес которой является шаблонным аргументом, должна иметь внешнюю связь (ехгегпа! (!п)гаке). Статические функции можно легко превратить в функции с внешней связью, удалив ключевое слово зтат1с и поместив их в безымянное пространство имен. Например, в стандартном пространстве имен языка С+ч- можно объявить следуюшую функцию. зтат1с чо1д гопО; х Я убежден, что решение этой проблемы сушествует.

Однако, увы, срок работы иад книгой ограничен контрактом. 297 Глава 11. Мультиметоды В безымянном пространстве имен эта функция объявляется иначе. павезрасе ( чо)д ьопО; Используя указатель на функцию в качестве шаблонного параметра, лишенного типа, мы отказываемся хранить его в ассоциативном массиве. Этот важный момент следует хорошо уяснить. Мы поступаем так потому, что компилятор обладает статической информацией об этом указателе.

Следовательно, компилятор может зафиксировать адрес функции в трамплинном коде. Эту идею можно реализовать в новом классе, используюшем класс вазлсп1зратйсег в качестве внугреннего буфера (ЬасЕ епд). Новый класс гпобзратсйег предназначен для диспетчеризации только функций, а не функторов. Он включает класс ваззсоззратсйег в свой закрытый' раздел и предоставляет соответствуюшие интерфейсные функции. Шаблонная функция глоб зратсйег::АгЫ имеет три шаблонных параметра. Два из них представляют собой левый и правый типы, для которых регистрируется диспетчеризация (классы сопсгетеьйз и сопсгетеяйз). Третий шаблонный параметр (са11Ьасй) является указателем на функцию. Дополнительная функция гпо1 зратсйег::АгЫ перегружает определенную выше шаблонную функцию АгЫ, имеюшую только два параметра.

теюр1ате <с1аээ вазеьйэ, с1азз вазеяйэ = вазеьйэ. яези1ттуре = чо1д> с1аэв гпо)зратсйег вазео)зратсйег<вазеьйз, вазеяйз, яези1ттуре> Ьасйяпд риЬ)зс: теар1ате<с1аээ сопсгетеьйэ, с1азз сопсгетеяйэ, яезо1ттуре (*са11Ьаск)(сопсгетеьйзб, сопсгегеяйзб)> чобд АдоС) ( зтгисг ьоса1 О см. главу 2 ( зтат)с аеэц1ттуре тгарво11пе(вазеьйэб 1Ьз, вазеайзй гйа) ( гетцгп са11Ьаск( дупав)с сайт<сопсгетеьйзй>(1йз), бував)с сазт<сопсгетеайзй>(гйз)); гетцго Ьаскдпд .Адд<сопсгетеьйз, сопсгетеяйз>( йьоса1::тгавро1)пе); Используя локальную структуру,мы определяем трамплинную функцию непосредственно внутри функции АгЫ.

Трамплинная функция осуществляет приведение аргументов к соответствующим типам, а затем передает управление функции, на которую ссылается указатель обратного вызова. Функция АгЫ добавляет трамплинную функцию в объект са11Ьаскмар с помощью функции АсЫ объекта Ьаскдпд (определенной в классе вазепбзратсйег). С точки зрения быстродействия трамплинная функция не создает дополнительных проблем.

Хотя она выглядит как косвенный вызов, это не так. Как указывалось выше, компилятор фиксирует адрес, храняшийся в указателе обратного вызова, в коде функции тгавро1)пе, поэтому второй косвенный вызов не возникает. Более изошренные Часть й. Компоненты 298 компиляторы при малейшей возможности делают трамплинную функцию подставляемой. Использовать новую функцию Ацц легко, суредеУ япп1зрасснег<внаре> п1зрасснег; О возможно в безымянном пространстве имен чо16 насснцессапд1еяо1у(аессапй1ей 1Ьз, по!уй гнз) п1зрасснег 01зр; Нзр.лйб<аессапй1е, яо1у, нассн>0; Благодаря функции-члену лдд класс япп1зрасснег легко использовать.

Он также позволяет при необходимости обращаться к функции лдд, определенной в классе вазеотзрасснег.' 11.7. Класс р п01ара1сйег и симметрия Благодаря динамизму класса гпп1зрасснег добавить в него поддержку симметрии намного проще, чем в статический класс всас1сп1зрасснег. Для этого достаточно зарегистрировать две трамплинные функции: одну — лля вызова исполняющей функции при обычном порядке следования аргументов, а вторую — для перестановки параметров перед вызовом.

Добавим в функцию лоо новый шаблонный параметр. сеир1асе <с1аьл вазеьнз, с1азл вазеяйз = вазелина, сурепаве яезц1стуре = чо1д> с1азз гпп1зрасснег сеир1асе <с1азз сопсгесеьнз, с1авл сопсгесецнз, яезц1стуре (ьса11Ьаск)(сопсгесеснзе, сопсгесеянзе), Ьоо1 зуиаесг1с> Ьоо! БИО с лсгцсс соса! ( ... траыплииная функция остается прежней ... зсас1с чо1б тгааро11пе(вазеянзе гнз, вазесЬзб 1Ьз) ( гесцгп тгааро11пе(1Ьз, гнз); лцц<сопсгесеснз, сопсгесеанз>(еьоса1::тгаиро1тпе); тб (зуваесг1с) лдд<сопсгесецнз, сопсгесеснз>(есоса1::тгаиро11пеа); ) ) ); з Функцию >пп1зрасснег:: лдб нельзя использовать только для регистрации динамически загружаемых функций.

Для того чтобы зто стало возможно, в программу нужно внести небольшие изменения. Глава 11. Мультиметоды Симметричная диспетчеризация в классе гпо1зрассЬег реализована на уровне функций — лля кажюй зарегистрированной функции принимается отдельное решение. 11.8. Двойная диспетчеризация функторов Трюк с трамплинными функциями хорошо работает с нестатическими функциями. Безымянные пространства имен предоставляют ясный способ замены статических функций нестатическими, которые невидимы эа пределами данной единицы компиляции: Однако иногда нужно, чтобы объект обратного вызова (шаблонный параметр Са11Ьасктуре класса ваз(со)зрассЬег) представлял собой нечто большее, чем обычный указатель на функцию. Например, можно потребовать, чтобы каждый обьект обратного вызова сохранял определенное состояние, в то время как функции могут сохранять только значения статических переменных.

Следовательно, возникает необхолимость регистрировать для лвойной диспетчеризации функторы, а не функции. Функторы (глава 5) — это классы, которые перегружают оператор вызова функции О, имитируя синтаксис вызова простой функции. Кроме того, функторы могут использовать переменные-члены для хранения своего состояния и доступа к нему. К сожалению, трюк с трамплинными функциями не применим к функторам именно потому, что функторы сохраняют свое состояние, а простые функции — нет.

(А где трамплинные функции могли бы хранить свое состояние?) Клиентский код может непосредственно использовать класс ваззсо(зрассЬег, конкретизированный соответствующим типом функтора. зсгцсс нассЬгипссог ( чо(б орегасог() (вЬаре8, вЬареб) ( суредеГ ваз(соэ'зрассЬег<вЬаре„ вЬаре, чозд, нассЬьцпссог> нассЬ1пооззрассЬег; Функция нассЬгипссог::орегасогс не является виртуальной, поскольку классу ва- з(со) зрассЬег нужен функтор, имеющий семантику значений, а она плохо согласуется с динамическим полиморфизмом.

Однако функция нассЬгцпссог::орегасогО может пе- реадресовать вызов виртуальной функции. Горазло хуже, что клиент теряет возможности автоматизации, предоставленные диспетчером, — привеление типов и поддержку симметрии. Похоже, что мы слелали шаг назад, но только если вы не читали главу 5 об обобщен- ных функторах. В этой главе определен класс ьцпссог, способный содержать любые функ- торы и указатели на функции, а также объекты самого класса гипссог. Можно даже опре- делять специализированные объекты класса гцпссог, вьводя их из класса гипссогтмр1. В классе вцпссог можно определить приведение типов. Поместив эти средства в библиотеку, можно легко реализовать симметричную диспетчеризацию. Определим класс вцпссого(зрассЬег лля любых объектов класса гипссог.

Этот дис- петчер содержит класс вазэсо( эрассЬег„хранящий внутри себя объекты класса гцпссог. севр1асе <с1азз вазеьЬз, с1аев вазеябв - вазеьЬз, сурепале яезц1стуре = чеза> с1аав гцпссого1эрассЬег ( 300 Часть П. Компоненты суредет гипссог<яези1стуре, тугествт 2(вазеьвзб, вазекбзб)> гипссогтуре; суреде1 ваз1спззрассбег<вазесбз, вазеябз, яези1стуре, гипссогтуре> Васйепдтуре; вас1епдтуре ЬасМепд риЬ11с: Класс гипссогп1зрассбег использует конкретизацию класса ваз1со1зрассбег в качестве выходного буфера.

Класс вазтсо1зрассбег хранит объекты типа гипссогтуре. Они представляют собой объекты класса гипссог, получаюшие два параметра (классов вазесбз н вазеябв) и возврашаюшие объект класса яези1стуре. Функция-член гипссого1зрассвег: гддд определяет специализированный класс ддарсег, производный от класса гипссогтар1. Этот класс предназначен для приведения типов.

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

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

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