Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса

Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса

Авторы:

Жанр: Программирование

Циклы: не входит в цикл

Формат: Полный

Всего в книге 3 страницы. У нас нет данных о годе издания книги.

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

Читать онлайн Вариации на тему STL. Адаптер обобщенного указателя на функцию-член класса


Предисловие

Я думаю, большинство из тех, кто использует C++ согласятся, что STL – это хорошо. Это удобная, легкая, хорошо переносимая библиотека, которая прекрасно расширяется и не содержит решений, которые были сделаны только в силу вкусов кого-либо из авторов. В этом она совпадает по духу с основным принципом C++, провозглашенным Бьярном Страуструпом в своей книге «Дизайн и эволюция C++» – никогда и никому не навязывать ничего насильственно. Но не все так гладко – часто приходится добавлять в библиотеку возможности, не предусмотренные стандартом. Иногда при этом также приходится бороться с неполной совместимостью компиляторов со стандартом C++.

Проблема обобщенных указателей

Что такое обобщенные указатели и почему они полезны

Представим себе некий объект, который имеет перегруженную операцию operator->(). Мы можем его представить себе как некий обобщенный указатель, который не является указателем в полном смысле этого слова, но «прикидывается» им. Мы можем использовать его для доступа к полям и методам некоего объекта. Можно придумать много разных применений для обобщенных указателей: реализация различных вариантов умных указателей, осуществляющих некоторую форму сборки мусора или просто ведущих статистику обращений к объектам, можно использовать обобщенные указатели для реализации паттерна «Proxy», когда мы вместо объекта используем обобщенный указатель на него, а сам объект прячется где-либо из соображений инкапсуляции, можем использовать их для реализации стратегий ленивых и сверхэнергичных вычислений и для многого другого. Видно, что обобщенные указатели – весьма полезная штука.

СОВЕТ Для того, чтобы понять всю мощь и красоту обобщенных указателей весьма полезно почитать такие книги, как «Эффективное использование C++» и «Наиболее эффективное использование C++» Скотта Мейерса, «C++: библиотека программиста» Джеффа Элджера, а также более общую книгу «Приемы объектно-ориентированного программирования. Паттерны проектирования» Эриха Гаммы, Ричарда Хелма, Ральфа Джонсона и Джона Влиссидеса.

Но в чем тогда проблема?

Обобщенный указатель всего лишь «прикидывается» указателем и не может быть использован везде, где используются обычные указатели. Например, возьмем адаптер указателя на функцию-член класса из STL:

>template

>mem_fun_t mem_fun(R (T::*pm)());


>template

>struct mem_fun_t: public unary_function {

> explicit mem_fun_t(R (T::*pm)());

> R operator()(T *p);

>};

Видно, что когда мы вызываем mem_fun(some_class::some_member), то получаем функциональный объект, который принимает указатель (обычный!) на объект класса some_class и вызывает функцию some_member по этому указателю. Но что будет, если мы попытаемся вызвать operator() с аргументом – обобщенным указателем на объект класса A, если у этого указателя нет неявного преобразования в указатель на объект класса?

ПРИМЕЧАНИЕ Такие объекты-заместители бывают нужны, если клиенту нельзя давать доступ к самому объекту: например, если тот размещен в специальной области памяти и его адрес может меняться после сборки мусора.

Обобщение mem_fun

Проблемы с интерфейсом mem_fun_t

Для начала обратим внимание на то, что mem_fun_t::operator() принимает только указатель на объект класса, чьим членом является функция pm. От этого было бы неплохо избавиться. Рассмотрим такой вариант:

>template

>struct gen_mem_fun_t {

> explicit gen_mem_fun_t(R (T::*pm)());

> R operator()(TT p);

>};

Сразу видна пара недостатков – во-первых, теперь адаптер может работать только с одним типом обобщенных указателей, а во-вторых, этот тип придется задавать при создании адаптера. Эти соображения должны натолкнуть нас на мысль воспользоваться шаблонными функциями-членами классов.

>template

>struct gen_mem_fun_t {

> explicit gen_mem_fun_t(R (T::*pm)());

> template R operator()(TT p);

>};

Теперь все хорошо – при необходимости вызвать operator() для специфичного обобщенного указателя сгенерируется своя функция operator().

Реализация gen_mem_fun_t

Рассмотрим реализацию mem_fun_t:

>template

>struct mem_fun_t {

> explicit mem_fun_t(R (T::*pm_)()): pm(pm>_) {}

> R operator()(T *p) const {return ((p->*pm)());}

>private:

> R (T::*pm)();

>};


Все кажется идеальным для работы с указателями, но ведь обобщенный указатель – это не указатель, он не знает, что такое operator->*! Нужно явно узнать, на какой объект он ссылается и потом уже выполнять операцию ->*

>template

>struct gen_mem_fun_t {

> explicit gen_mem_fun_t(R (T::*pm_)()): pm(pm_) {}

> template R operator()(TT p) {return (p.operator->()->*pm)();}

>private:

> R (T::*pm)();

>};

Правда, возникает другая одна проблема – если теперь мы захотим использовать наш адаптер с обычным указателем, то потерпим поражение: обычные указатели не понимают operator->(). Таким образом, нам необходимо специализировать нашу функцию operator() для работы с обычными указателями:

>template<>

>R operator()(T* p) {

> return (p->*pm)();

>}

Реализация gen_mem_fun

Теперь реализация gen_mem_fun становится тривиальной:


С этой книгой читают
Обработка событий в С++

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


Экстремальное программирование. Разработка через тестирование
Автор: Кент Бек

Возвращение знаменитого бестселлера. Изящный, гибкий и понятный код, который легко модифицировать, который корректно работает и который не подкидывает своим создателям неприятных сюрпризов. Неужели подобное возможно? Чтобы достичь цели, попробуйте тестировать программу еще до того, как она написана. Именно такая парадоксальная идея положена в основу методики TDD (Test-Driven-Development – разработка, основанная на тестировании). Бессмыслица? Не спешите делать скороспелые выводы. Рассматривая применение TDD на примере разработки реального программного кода, автор демонстрирует простоту и мощь этой методики.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Перевод в электронный формат, кодированные наборы шрифтов и система Оптического Распознавания Символов для многошрифтовых информационных ресурсов на примере “Летописи журнальных статей”

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


Геймдизайн. Рецепты успеха лучших компьютерных игр от Super Mario и Doom до Assassin’s Creed и дальше

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.


Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Антиабсурд, или Книга для тех, кто не любит читать

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


Война балбесов

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


Под напряжением
Жанр: Детектив

В центре Нью-Йорка совершено ужасное преступление: мощнейшим электрическим разрядом убиты пассажиры автобуса.Но это только начало! Убийца, виртуозно обращающийся с электричеством, оставляет за собой все новые и новые жертвы, при этом заранее предупреждая полицию о точном времени следующего преступления.В городе начинается паника, и тогда к делу подключаются гений криминалистики Линкольн Райм и его помощница — детектив Амелия Сакс.Райму удается вычислить преступника, но его поиски превращаются в гонку со временем — ведь до следующего смертоносного разряда всего несколько часов…


Теряя маски

Даже самый лучший план действует лишь до начала его осуществления. Эту мудрость в очередной раз ощутил на себе Максим Рудов (он же Сакурай Синдзи), распланировавший свою жизнь до совершеннолетия. Но вот счастливая случайность — и наш герой оказывается в центре набирающей ход горной лавины событий. Взаимоотношения с аристократами, проблемы с конкурентами, начинающаяся война с боссом одной из преступных гильдий… А еще школа, друзья и люди, зависящие от него.Уже сброшена маска обычного японского школьника, маска бойца ранга Ученик для все большего числа окружающих не в состоянии скрыть реальную (или почти реальную) силу героя, маска вора-виртуоза Токийского Карлика становится все более неудобной.


Поделиться мнением о книге