Идиомы и стили С++ - [9]
В какой-то степени по этой причине, но так же и по некоторым другим соображениям, в C++ применяется прием двухэтапной инициализации. На мой взгляд это не есть идиома, а довольно простой прием, но есть весьма важная причина, почему я должен о нем рассказать: его не используют.
Особенно часто этим грешат начинающие Delphi-щики, и VB-шники: слишком велик соблазн щелкнуть по методу формы OnCreate, OnShow (Form_Create, Form_Show), и прописывать инициализации там, или, что еще ужаснее, залезть из одной формы в другую и там изменять значения переменных. Не делайте этого! Граждане дельфинщики! Форма - такой же класс, как и все остальные. Не лишайте ее законного конструктора, дайте ей заслуженную инициализацию! Не чмарите свой инструмент, и он воздаст Вам сторицей!
Ну ладно, чувствую я тут возбужденный такой забуду код нарисовать. Сначала пояснения. Пусть Ваш класс управляет Темными Силами, и они лежат в закрытой части объявления. Не ввязывайтесь в борьбу с ними в конструкторе, там они слишком злобно гнетут. Конструктор пусть инициализирует только примитивные типы, он к тому же их оптимизирует ловчее, но фактически его дело - только выделить память и получить указатель на объект. Инициализация Темных Сил - дело специальной функции, которая грамотно выполняет все нужные действия.
>class CClass {
>private:
>// Чудовищно сложные структуры, ресурсы,
>// мьютексы-шмутексы, все сплошь критическое,
>// пачками выбрасывающие исключения.
>public:
> CClass (); // Конструктор, которому на Ваши проблемы плевать.
> // Вот тут мы и замучаем свои ресурсы.
> int InitInstance (‹список аргументов›) throw (‹список исключений›);
>};
>// Где-то в коде:
>CClass* cc = new CClass;
>if (cc != NULL) {
> try {
> int ret_code = cc-›InitInstance();
> // Тут еще и код возврата можно обработать, если не лень,
> // но только если инициализация прошла успешно.
> // если выскочило исключение, сюда мы не попадем.
> } catch (…) {
> // да еще и исключения обработать.
> }
>};
Все…
Шаг 13 - Перегрузка operator+.
Оператор operator-› мы уже перегружали. Результаты получились просто феерические. Давайте замучаем еще кого-нибудь и посмотрим, что получится? Давайте. Первейшим кандидатом на переопределение является оператор operator+,потому что в жизни (помимо С++) он выражает замечательное действие - добавление объекта к другому объекту. Конечно, Вы можете придать ему и другой смысл, но это будет как раз тот случай, где "если хочешь быть здоров - ешь один, и в темноте"…
Проиллюстрирую сказанное следующим примером: Вы пишете интерфейс на Паскале, и для добавления подменю или пункта меню используете функции AddSubMenu() и AddMenuItem(). Тогда для создания меню Вы прописываете замечательно изящное выражение с толстым-толстым слоем скобок в конце:
>Menu.AddSubMenu(Submenu1,
> AddMenuItem(MenuItem1,
> AddMenuItem(MenuItem2,
> AddMenuItem(MenuItem3,
> AddSubMenu (SubMenu2, nil)
>))));
А вот что получается на С++:
>CMenu Menu = Menu() + SubMenu1() + MenuItem1() + MenuItem2() + MenuItem3() + SubMenu2();
Прошу извинить за отсутствие подробностей - на память не помню; но и так очевидно, что выражение в C++ выглядит просто красивее. Это одно из главных достоинств С++ - язык позволяет выражать наши намерения предельно ясно.
Есть еще один смысл, который можно придать оператору operator+, если "от перестановки мест слагаемых сумма не изменяется". Примером, кроме сложения и умножения чисел, может быть соударение объектов: столкнулся ли Титаник с айсбергом, айсберг ли столкнулся с Титаником, результат один - вызов деструктора для Титаника. (Я не утверждаю, что это НУЖНО делать так, это только можно!)
Немного ниже мы используем это для уменьшения количества диспетчерских функций при двойной диспетчеризации из Шага 4, а сейчас быстренько напишем код с переопределением operator+ для любимого стека всех времен и народов. Понятно, на месте стека может оказаться каждый, те же меню, опять же.
>class CArray {
>private:
> int a[100];
> int iTop;
>public:
> CArray ():iTop(0) {}
> CArray (const CArray& _ca) {
> iTop = _ca.iTop;
> for (int i=0; i++; i ‹100) a[i]= _ca.a[i];
> }
> CArray& operator=(const CArray& _ca) {
> if (this==&_ca) return *this;
> for (int i=0; i++; i ‹100) a[i]= _ca.a[i];
> iTop = _ca.iTop;
> return *this;
> };
> // С этим еще можно согласиться
> CArray& operator+ (int _i) { a[iTop]=_i; iTop++; return *this; }
> // Это пример дурного стиля
> int operator-- () { iTop--; return a[iTop+1]; }
>};
Для такого тестового стека определим оператор operator+ (и operator+=) для вставки объектов, а оператор operator- для выталкивания и удаления. Вы кстати знаете, что для operator++ и operator- есть постфиксная и префиксная форма? У постфиксной в скобках фиктивный параметр стоит:

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

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

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

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

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

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

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

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.