Идиомы и стили С++ - [5]

Шрифт
Интервал

). Вот код:

>// Это находится в заголовочном файле.

>class Cthat;

>class CPthat {

>private:

> Cthat* t; // обычный указатель на объект

>public:

> CPthat ();

> CPthat (const CPthat&);

> ~CPthat ();

> CPthat& operator=(const CPthat&);

> // Новый интерфейс - дубликат

> void funct1(void);

> void funct2(void);

>};


>// Это все содержится в cpp-файле.

>// и первое - определение указываемого объекта

>class Cthat {

> friend class CPthat;

>private:

>protected:

> Cthat();

>public:

> // Родной интерфейс.

> void funct1(void);

> void funct2(void);

>};


>//Реализация членов-функций класса указателя.

>CPthat::CPthat ():t(new Cthat) {}

>CPthat::CPthat (const CPthat& _cp):t(new Cthat(*(_cp.t))) {}

>CPthat::~CPthat (){ delete t; }

>CPthat& CPthat::operator=(const CPthat& _cp) {

> if (this != &_cp) {

>  delete t;

>  t = new Cthat(*(_cp.t));

> }

> return *this;

>}

>void CPthat::funct1(void) { t-›funct1(); }

>void CPthat::funct2(void) { t-›funct2(); }


>// Реализация членов-функций класса объекта

>Cthat::Cthat() {}

>void Cthat::funct1(void) {}

>void Cthat::funct2(void) {}

Все, приплыли. От класса указываемых объектов остался только перископ в виде class Cthat;, а более ничего. CPthat действует вместо него. Он сам стал им. Класс CPthat является классом интерфейсного указателя.

Теперь можете идти за пивом. Вы властелин вселенной. Вы можете превратить кого угодно во что угодно. Имея на вооружении идиомы умных, ведущих и интерфейсных указателей, сочетая их в любых комбинациях, Вы можете превратить в урода любой класс на выбор. Или в красавца. Ваше желание - закон, господин. Мне кажется, Вы уже знаете, о чем будет следующий шаг. Но я не могу подобрать нормального термина этому. Слово "интерфейс" заездили до последней степени. Скоро руль и педали назовут интерфейсом автомобиля к шоферу, а вилка, ложка и нож будут универсальным интерфейсом еды. И конечно, Мелкомякг именно это слово применил для следующей идеи. А еще это называют "suite" - комплект, или "facet" - грань. В общем, следующий шаг - о множественных интерфейсных указателях на объект.

Шаг 8 - Еще раз о статистике класса.

Пока праздники не начались и не кончились, пока работает интернет и библиотека, снова займемся любимым делом - статистикой класса. Мы уже говорили о ней, и уяснили, что здесь неплохо работает идиома ведущих указателей. Но на плюсах работает в течение 20 лет сотни тысяч программеров, и было бы неверно предположить, что они за это время не изобрели иных приличных способов реализовать статистику. Так… что же они там навыдумывали?

Мысль о классе, ответственном за статистику, приходит быстро. Да, это работает, но как только иерархия классов разрастается, увеличивается количество геморроя. Наследование становится множественным, потом виртуальным, статические члены сохраняются в классах мертвым грузом… ну в небольших иерархиях работает, но я не для этого взялся за шаг.

Изящную идиому предложил Коплин в 1995 году, а Мейерс развил ее в 2000. Правда, она предполагает вмешательство в код класса, но это не мешает быть очаровательно красивой. Основана она на том, что мы определяем шаблон класса счетчика и втыкаем его наблюдаемый класс статическим членом или наследованием. Шаблон расширяется ровно один раз для каждого класса, и это гарантирует нам наличие ровно одного экземпляра статистики. Код лучше объяснит.

>// Это шаблон класса, ответственного за статистику.

>template ‹class T›

>class CCounter {

>public:

> CCounter() { ++m_iCount; }

> CCounter(const CCounter&) { ++m_iCount; }

> ~CCounter() { --m_iCount; }

> static int GetCount() { return m_iCount; }

>private:

> static int m_iCount;

>};


>// Парашютики, парашютики берем не забываем!

>// Инициализируем статическую мембер-переменную.


>template ‹class T› int CCounter‹T›::m_iCount = 0;


>// Использование статистики.

>class CClass {

>public:

> static int GetCount() { return CCounter‹CClass>::GetCount(); };

>private:

> CCounter‹CClass› cInstance;

>};

Нор убавить нейзер прибавить, сказать нечего, разве вместо неуместного int поставьте size_t. Это макрос, он расширяется в зависимости от модели памяти или в int или в long. Я уж чтоб народ не смущать, в конце концов сайт называется "Первые Шаги", а не Последний Путь. Можно применить наследование, но не советую. Мейерс нашел какие-то преимущества, но меня не убедил.

Да еще это КРАЙНЕ важно - модификатор const в объявлении функций - не гнушайтесь его юзать! Если функция не изменяет ничего в классе, ставьте не ленясь. Если кто-то захочет позже использовать ее в константной функции, то не сможет - без вмешательства в код, а это надо? Шансы на то, что этот кто-то будете Вы, но более опытный, крайне велики. Трудно набирать? Купите себе кривую клаву и потренируйтесь месячишко стучать вслепую. Эта инвестиция окупится, уверяю Вас как специалист по фондовому рынку. То же с аргументами, передаваемыми в функцию. Не забывайте, что const изменяет сигнатуру функции.

Шаг 9 - Множественные интерфейсные smart-указатели.

Вполне возможно, что Вы работаете с действительно крупным проектом, иерархия классов развилась до огромных размеров, а каждый класс (особенно внизу иерархии) обладает десятками или сотнями открытых функций. Конечно, неплохо задаться вопросом "Насколько разумно это?". Еще лучше, если этот вопрос задать до начала написания кода. Тогда можно вовремя почитать Гради Буча, установить на компьютер "


Еще от автора Альберт Махмутов
Человек! Чего же ты хочешь, скажи!

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


И всё-таки люди созданы для счастья

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


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

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


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

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