Эффективное использование STL - [39]
Задача сравнения объектов возникает в STL очень часто. Например, если функция >find
ищет в интервале первый объект с заданным значением, она должна уметь сравнивать два объекта и узнавать, совпадают ли их значения. При попытке включения нового элемента в множество функция >set::insert
должна проверить, не существует ли данное значение в контейнере.
Совет 19. Помните о различиях между равенством и эквивалентностью
Алгоритм >find
и функция >set::insert
являются типичными представителями семейства функций, проверяющих совпадение двух величин, однако делают это они по-разному. Для >find
совпадением считается равенство двух величин, проверяемое оператором >==
. Функция >set::insert
проверяет отношение эквивалентности, обычно основанное на операторе ><
. Таким образом, по одному определению два объекта могут иметь одинаковые значения, тогда как по другому определению они будут различаться. Отсюда следует, что для эффективного использования STL необходимо понимать различия между равенством и эквивалентностью.
Формальное определение равенства основано на использовании оператора >==
. Если результат выражения >x==y
равен >true
, значит, >x
и >y
имеют одинаковые значения, а если >false
— разные. В целом определение весьма прямолинейное, хотя следует помнить о том, что из равенства значений не следует равенство всех полей данных. Предположим, класс >Widget
хранит внутренние данные о времени последнего обращения:
>class Widget {
>public:
> …
>private:
> TimeStamp lastAccessed;
>};
Для класса >Widget
можно определить оператор >==
, игнорирующий значение этого поля:
>bool operator==(const Widgets lhs, const Widgets rhs) {
> // Поле lastAccessed игнорируется
>}
В этом случае два объекта >Widget
будут считаться равными даже в том случае, если их поля >lastAccessed
содержат разные значения.
Эквивалентность основана на относительном порядке значений объектов в отсортированном интервале. Проще всего рассматривать ее в контексте порядка сортировки, являющегося частью любого стандартного ассоциативного контейнера (то есть >set
, >multiset
, >map
и >multimap
). Два объекта >x
и >y
считаются эквивалентными по отношению к порядку сортировки, используемому ассоциативным контейнером >c
, если ни один из них не предшествует другому в порядке сортировки >c
. На первый взгляд такая формулировка кажется запутанной, но на практике все просто. Возьмем контейнер >set
. Два объекта >Widget
, >w1
и >w2
, имеют эквивалентные значения по отношению к >s
, если ни один из них не предшествует другому в порядке сортировки >s
. Стандартная функция сравнения для >set
— >less
— по умолчанию просто вызывает >operator<
для объектов >Widget
, поэтому >w1
и >w2
будут иметь значения, эквивалентные по отношению к >operator<
если истинно следующее выражение:
>!(w1
>&& // и
>!(w2
Все вполне логично: два значения эквивалентны (по отношению к некоторому критерию упорядочения), если ни одно из них не предшествует другому в соответствии с данным критерием.
В общем случае функцией сравнения для ассоциативного контейнера является не оператор ><
или даже >less
, а пользовательский предикат (см. совет 39). Каждый стандартный ассоциативный контейнер предоставляет свой предикат сортировки через функцию >key_comp
, поэтому два объекта >x
и >y
имеют эквивалентные значения по отношению к критерию сортировки ассоциативного контейнера >c
, если выполняется следующее условие:
>!c.key_comp()(x, y) && !c.key_comp()(y, x) // х не предшествует у
>// в порядке сортировки с,
>// а у не предшествует х
Выражение >!c.key_comp()(x,y)
выглядит устрашающе, но стоит понять, что >c.key_comp()
возвращает функцию (или объект функции), как все затруднения исчезают. Перед нами простой вызов функции (или объекта функции), возвращаемой >key_comp
, которой передаются аргументы >x
и >y
. Затем вычисляется логическое отрицание результата. Функция >с.keycomp()(х, у)
возвращает >true
лишь в том случае, если >x
предшествует >y
в порядке сортировки, поэтому выражение >!с.key_comp()(х, у)
истинно только в том случае, если >x
не предшествует >y
в порядке сортировки >c
.
Чтобы вы лучше осознали принципиальный характер различий между равенством и эквивалентностью, рассмотрим пример — контейнер >set
без учета регистра символов, то есть контейнер >set
, в котором функция сравнения игнорирует регистр символов в строках. С точки зрения такой функции строки «STL» и «stL» эквивалентны. Пример реализации функции >ciStringCompare
, игнорирующей регистр символов, приведен в совете 35, однако >set
требуется типфункции сравнения, а не сама функция. Чтобы заполнить этот пробел, мы пишем класс функтора с оператором >()
, вызывающим >ciStringCompare
:
>struct CiStringCompare: // Класс сравнения строк
>public // без учета регистра символов;
>binary_function
> // приведено в совете 40
>bool operator() (const string& lhs, const string& rhs) const {
> return ciStringCompare(lhs, rhs); // Реализация ciStringCompare
> // приведена в совете 35
Эффективный и современный С++Освоение С++11 и С++14 — это больше, чем просто ознакомление с вводимыми этими стандартами возможностями (например, объявлениями типов auto, семантикой перемещения, лямбда-выражениями или поддержкой многопоточности). Вопрос в том, как использовать их эффективно, чтобы создаваемые программы были корректны, эффективны и переносимы, а также чтобы их легко можно было сопровождать. Именно этим вопросам и посвящена данная книга, описывающая создание по-настоящему хорошего программного обеспечения с использованием C++11 и С++14 — т.е.
Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Сейчас во многих школах, институтах и других учебных заведениях можно встретить компьютеры старого парка, уже отслужившие свое как морально, так и физически. На таких компьютерах можно изучать разве что Dos, что далеко от реалий сегодняшнего дня. К тому же у большинства, как правило, жесткий диск уже в нерабочем состоянии. Но и выбросить жалко, а новых никто не дает. Различные спонсоры, меценаты, бывает, подарят компьютер (один) и радуются, как дети. Спасибо, конечно, большое, но проблемы, как вы понимаете, этот компьютер в общем не решает, даже наоборот, усугубляет, работать на старых уже как-то не хочется, теперь просто есть с чем сравнивать.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.
Что общего между самыми востребованными профессиями и стремительным увеличением количества информации в мире? Ответ: язык структурированных запросов (SQL). SQL — рабочая лошадка среди языков программирования, основа основ для современного анализа и управления данными. Книга «SQL: быстрое погружение» идеальна для всех, кто ищет новые перспективы карьерного роста; для разработчиков, которые хотят расширить свои навыки и знания в программировании; для любого человека, даже без опыта, кто хочет воспользоваться возможностями будущего, в котором будут править данные.
Даже плохой программный код может работать. Однако если код не является «чистым», это всегда будет мешать развитию проекта и компании-разработчика, отнимая значительные ресурсы на его поддержку и «укрощение». Эта книга посвящена хорошему программированию. Она полна реальных примеров кода. Мы будем рассматривать код с различных направлений: сверху вниз, снизу вверх и даже изнутри. Прочитав книгу, вы узнаете много нового о коде. Более того, вы научитесь отличать хороший код от плохого. Вы узнаете, как писать хороший код и как преобразовать плохой код в хороший. Книга состоит из трех частей.
Книга "Изучаем Python" - это ускоренный курс, который позволит вам сэкономить время и сразу начать писать работоспособные программы (игры, визуализации данных, веб-приложения и многое другое). Хотите стать программистом? В первой части книги вам предстоит узнать о базовых принципах программирования, познакомиться со списками, словарями, классами и циклами, вы научитесь создавать программы и тестировать код. Во второй части книги вы начнете использовать знания на практике, работая над тремя крупными проектами: создадите собственную "стрелялку" с нарастающей сложностью уровней, займетесь работой с большими наборами данных и освоите их визуализацию, и, наконец, создадите полноценное веб-приложение на базе Django, гарантирующее конфиденциальность пользовательской информации. Если вы решились разобраться в том что такое программирование, не нужно ждать.
Алгоритмы - это всего лишь пошаговые алгоритмы решения задач, и большинство таких задач уже были кем-то решены, протестированы и проверены. Можно, конечно, погрузится в глубокую философию гениального Кнута, изучить многостраничные фолианты с доказательствами и обоснованиями, но хотите ли вы тратить на это свое время? Откройте великолепно иллюстрированную книгу и вы сразу поймете, что алгоритмы - это просто. А грокать алгоритмы - это веселое и увлекательное занятие.