C++. Сборник рецептов - [125]

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

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

Большая часть стандартных операторов имеет несколько значений, и в общем случае вы должны следовать общепринятым соглашениям. Например, оператор ><< означает битовый сдвиг влево или, при работе с потоками, помещение чего-либо в поток, как здесь.

>cout << "Это записывается в поток стандартного вывода.\n.";

Если вы решите перегрузить ><< для одного из своих классов, он должен делать одно из этих действий или, по крайней мере, аналогичное им. Перегрузка оператора — это одно, а придание им другого семантического смысла — это совсем другое. Если вы не вводите новое соглашение, повсеместно используемое в вашем приложении или библиотеке (что все равно является плохой идеей), и оно не является интуитивно понятным кому-либо еще, кроме вас, следует строго придерживаться стандартных значений.

Чтобы эффективно перегрузить операторы, требуется проделать большое количество черновой работы. Но ее требуется проделать только один раз, и она будет окупаться каждый раз, когда ваш класс будет использоваться в простых выражениях. При умеренном и разумном использовании перегрузки операторов она может сделать код легким как для чтения, так и для написания.

Смотри также

Рецепт 8.13.

8.15. Вызов виртуальной функции родительского класса

Проблема

Требуется вызвать функцию родительского класса, но она переопределена в производном классе, так что обычный синтаксис >p->method() не дает нужного результата.

Решение

Укажите полное имя вызываемого метода, включая имя родительского или базового класса (если есть только два класса, например). (См. пример 8.16.)

Пример 8.16. Вызов определенной версии виртуальной функции

>#include


>using namespace std;


>class Base {

>public:

> virtual void foo() {cout << "Base::foo()" << endl;}

>};


>class Derived : public Base {

>public:

> virtual void foo() {cout << "Derived::foo()" << endl;}

>};


>int main() {

> Derived* p = new Derived();

> p->foo();       // Вызов версии производного класса

> p->Base::foo(); // Вызов версии базового класса

>}

Обсуждение

Регулярное использование переопределения полиморфных возможностей C++ является плохой идеей, но иногда это требуется сделать. Как и в случае с большинством других методик С++, это по большей части вопрос синтаксиса. Когда требуется вызвать определенную версию виртуальной функции базового класса, просто укажите ее имя после имени этого класса, как это сделано в примере 8.16.

>p->Base::foo();

Здесь будет вызвана версия >foo, определенная в >Base, а не та, которая определена в каком-то из подклассов >Base, на который указывает >p.

Глава 9

Исключения и безопасность

9.0. Введение

Данная глава содержит рецепты по обработке исключений в С++. Язык C++ обеспечивает необходимую поддержку работы с исключениями, и, используя некоторые приемы, вы сможете создавать программный код, в котором исключительные ситуации эффективно обрабатываются и легко отлаживаются.

Первый рецепт описывает семантику C++ по выбрасыванию (throwing) и перехвату (catching) исключений и затем показывает, как создавать класс для представления исключений. Это является хорошей отправной точкой, если у вас мало или совсем нет опыта работы с исключениями. Здесь описываются также стандартные классы исключений, определенные в заголовочных файлах > и >.

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

9.1. Создание класса исключения

Проблема

Требуется создать свой собственный класс исключения, предназначенный для выбрасывания и перехвата исключений.

Решение

Вы можете выбрасывать (>throw) или перехватывать (>catch) любые типы С++, которые удовлетворяют некоторым простым требованиям, а именно имеют конструктор копирования и деструктор. Однако исключения являются сложными объектами, поэтому при проектировании класса, который представляет исключительные ситуации, необходимо рассмотреть ряд вопросов. Пример 9.1 показывает, каким может быть простой класс исключения.

Пример 9.1. Простой класс исключения

>#include

>#include


>using namespace std;


>class Exception {

>public:

> Exception(const string& msg) : msg_(msg) {}

> ~Exception() {}


Рекомендуем почитать
Изучаем Java EE 7

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


Pro Git

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


Java 7

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


Создаем порт для FreeBSD своими руками. Часть II

Система сборки программ, используемая во FreeBSD, имеет значительно большие возможности, чем те, которые мы задействовали. Какие это возможности и как их использовать в своих портах?


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

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


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.