Читаем Стандарты программирования на С++ полностью

Имеются высокоспециализированные библиотеки (например, генераторы синтаксических анализаторов), в предметной области которых соглашения о семантике операторов существенно отличаются от их значений в С++ (например, при работе с регулярными выражениями оператор operator* может использоваться для выражения "ноль или большее количество"). Предпочтительно найти альтернативу необычной перегрузке оператора (например, в регулярных выражениях [C++TR104] используются строки, так что * может использоваться естественным образом, без перегрузки операторов). Если все же после тщательных размышлений вы решили использовать операторы, убедитесь, что вы четко определили единую схему для всех ваших соглашений, и при этом не затеяли опасные игры со встроенными операторами.

Ссылки

[Cline99] §23.02-06 • [C++TR104] §7 • [Dewhurst03] §85-86 • [Koenig97] §4 • [Lakos96] §9.1.1 • [Meyers96] §6 • [Stroustrup00] §11.1 • [Sutter00] §41

<p>27. Отдавайте предпочтение каноническим формам арифметических операторов и операторов присваивания</p>Резюме

Если можно записать а+b, то необходимо, чтобы можно было записать и a+=b. При определении бинарных арифметических операторов одновременно предоставляйте и их присваивающие версии, причем делайте это с минимальным дублированием и максимальной эффективностью.

Обсуждение

В общем случае для некоторого бинарного оператора @ (+, -, * и т.д.) вы должны также определить его присваивающую версию, так чтобы a@=b и a=a@b имели один и тот же смысл (причем первая версия может быть более эффективна). Канонический способ достижения данной цели состоит в определении @ посредством @= следующим образом:

T& T::operator@=(const T&) {

 // ... реализация ...

 return *this;

}

T operator@(const T& lhs, const T& rhs) {

 T temp(lhs);

 return temp @= rhs;

}

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

Обратите внимание, что здесь operator@ — функция-не член, так что она обладает желательным свойством возможности неявного преобразования как левого, так и правого параметра (см. рекомендацию 44). Например, если вы определите класс String, который имеет неявный конструктор, получающий аргумент типа char, то оператор operator+(const String&, const String&), который не является членом класса, позволяет осуществлять операции как типа char+String, так и String+char; функция-член String::operator+(const String&) позволяет использовать только операцию String+char. Реализация, основной целью которой является эффективность, может определить ряд перегрузок оператора operator@, не являющихся членами класса, чтобы избежать увеличения количества временных переменных в процессе преобразований типов (см. рекомендацию 29).

Также делайте не членом функцию operator@= везде, где это возможно (см. рекомендацию 44). В любом случае, все операторы, не являющиеся членами, должны быть помещены в то же пространство имен, что и класс T, так что они будут легко доступны для вызывающих функций при отсутствии каких-либо сюрпризов со стороны поиска имен (см. рекомендацию 57).

Как вариант можно предусмотреть оператор operator@, принимающий первый параметр по значению. Таким образом вы обеспечите неявное копирование компилятором, что обеспечит ему большую свободу действий по оптимизации:

T& operator@=(T& lhs, const T& rhs) {

 // ... реализация ...

 return lhs;

}

T operator@(T lhs, const T& rhs) { // lhs передано по значению

 return lhs @= rhs;

}

Еще один вариант — оператор operator@, который возвращает const-значение. Эта методика имеет то преимущество, что при этом запрещается такой не имеющий смысла код, как a+b=c, но в этом случае мы теряем возможность применения потенциально полезных конструкций наподобие а = (b+c).replace(pos, n, d). А это весьма выразительный код, который в одной строчке выполняет конкатенацию строк b и с, заменяет некоторые символы и присваивает полученный результат переменной а.

Примеры

Пример. Реализация += для строк. При конкатенации строк полезно заранее знать длину, чтобы выделять память только один раз:

Перейти на страницу:

Все книги серии C++ In-Depth

Стандарты программирования на С++
Стандарты программирования на С++

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

Андрей Александреску , Герб Саттер

Программирование, программы, базы данных

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных

Все жанры