Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14 - [33]

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

Следует запомнить

• Перечисления в стиле С++98 в настоящее время известны как перечисления без областей видимости.

• Перечислители перечислений с областями видимости видимы только внутри перечислений. Они преобразуются в другие типы только с помощью явных приведений.

• Как перечисления с областями видимости, так и без таковых поддерживают указание базового типа. Базовым типом по умолчанию для перечисления с областью видимости является >int. Перечисление без области видимости базового типа по умолчанию не имеет.

• Перечисления с областями видимости могут быть предварительно объявлены. Перечисления без областей видимости могут быть предварительно объявлены, только если их объявление указывает базовый тип.

3.5. Предпочитайте удаленные функции закрытым неопределенным

Если вы предоставляете код другим разработчикам и хотите предотвратить вызов ими некоторой функции, обычно вы просто ее не объявляете. Нет объявления функции — нечего и вызывать. Но иногда С++ объявляет функции вместо вас, и если вы хотите предотвратить вызов таких функций клиентами вашего кода, придется постараться.

Эта ситуация возникает только для “специальных функций-членов”, т.e. функций-членов, которые при необходимости С++ генерирует автоматически. В разделе 3.11 эти функции рассматриваются более подробно, а пока что мы будем беспокоиться только о копирующем конструкторе и копирующем операторе присваивания. Эта глава во многом посвящена распространенным практикам С++98, для которых есть более эффективная замена в С++11, а в С++98, когда вы хотите подавить применение функции-члена, это почти всегда копирующий конструктор, оператор присваивания или они оба.

Подход С++98 для предотвращения применения этих функций состоит в объявлении их как >private без предоставления определений. Например, вблизи с основанием иерархии потоков ввода-вывода в стандартной библиотеке С++ находится шаблонный класс >basic_ios. Все классы потоков наследуют (возможно, косвенно) этот класс. Копирование потоков ввода-вывода нежелательно, поскольку не совсем очевидно, что же должна делать такая операция. Объект >istream, например, представляет поток входных значений, одни из которых могут уже быть считаны, а другие могут потенциально быть считаны позже. Если копировать такой поток, то должно ли это повлечь копирование всех считанных значений, а также значений, которые будут считаны в будущем? Простейший способ разобраться в таких вопросах — объявить их несуществующими. Именно это делает запрет на копирование потоков.

Чтобы сделать классы потоков некопируемыми, >basic_ios в С++98 объявлен следующим образом (включая комментарии):

>template >

>class basic_ios : public ios_base {

>public:

> …

>private:

> basic_ios(const basic_ios&);            // Не определен

> basic_ios& operator=(const basic_ios&); // Не определен

>};

Объявление этих функций как private предотвращает их вызов клиентами. Умышленное отсутствие их определений означает, что если код, все еще имеющий к ним доступ (т.e. функции-члены или друзья класса), ими воспользуется, то компоновка (редактирование связей) будет неудачной из-за отсутствия определений функций.

В С++11 имеется лучший способ достичь по сути того же самого: воспользоваться конструкцией “>= delete”: чтобы пометить копирующий конструктор и копирующее присваивание как удаленные функции. Вот та же часть >basic_ios в С++11:

>template >

>class basic_ios : public ios_base {

>public:

>…

> basic_ios(const basic_ios& ) = delete;

> basic_ios& operator=(const basic_ios&) = delete;

>};

Отличие удаления этих функций от их объявления как >private может показаться больше вопросом вкуса, чем чем-то иным, но на самом деле в это заложено больше, чем вы думаете. Удаленные функции не могут использоваться никоим образом, так что даже код функции- члена или функций, объявленных как >friend, не будет компилироваться, если попытается копировать объекты >basic_ios. Это существенное улучшение по сравнению с поведением С++98, где такое некорректное применение функций не диагностируется до компоновки.

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

Важным преимуществом удаленных функций является то, что удаленной может быть любая функция, в то время как быть >private могут только функции-члены. Предположим, например, что у нас есть функция, не являющаяся членом, которая принимает целочисленное значение и сообщает, является ли оно “счастливым числом”:


Еще от автора Скотт Мейерс
Эффективное использование STL

В этой книге известный автор Скотт Мейерс раскрывает секреты настоящих мастеров, позволяющие добиться максимальной эффективности при работе с библиотекой STL.Во многих книгах описываются возможности STL, но только в этой рассказано о том, как работать с этой библиотекой. Каждый из 50 советов книги подкреплен анализом и убедительными примерами, поэтому читатель не только узнает, как решать ту или иную задачу, но и когда следует выбирать то или иное решение — и почему именно такое.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


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

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


Платформа J2Me

Эта книга научит вас, как разрабатывать программное обеспечение для платформы J2ME компании «Sun Microsystems». Эта книга придерживается стиля учебного пособия, это не справочное руководство.Цель — дать вам твердую основу в понятиях и техниках, которая даст вам возможность решиться на самостоятельную разработку качественных приложений.


Виртуальная библиотека Delphi

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


Обработка баз данных на Visual Basic.NET

Это практическое руководство разработчика программного обеспечения на Visual Basic .NET и ADO.NET, предназначенное для создания приложений баз данных на основе WinForms, Web-форм и Web-служб. В книге описываются практические способы решения задач доступа к данным, с которыми сталкиваются разработчики на Visual Basic .NET в своей повседневной деятельности. Книга начинается с основных сведений о создании баз данных, использовании языка структурированных запросов SQL и системы управления базами данных Microsoft SQL Server 2000.


Исчерпывающее руководство по написанию всплывающих подсказок

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


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.