Создание безымянных пространств имен.
Давайте теперь разберёмся, каким образом можно гарантировать корректность имени, присвоенного пространству, ведь может получиться, что неким пространствам имён были присвоены одинаковые имена. Как избежать подобного конфликта, спросите Вы?! Как это ни странно - создав пространство имен без имени!!! Это связано с тем, что если создать безымянное пространство, С++ автоматически даст ему уникальное имя, которое мы с Вами, естественно, не увидим. Однако, то что имя будет уникальным - факт неоспоримый. Синтаксис объявления безымянного пространства имен следующий:
В такой ситуации С++ позволяет обращаться к компонентам безымянного пространства через операцию :: без указания имени. Вам нет необходимости объявлять это пространство (да и возможности нет, так как имени Вы не знаете). Неявное объявление using namespace добавляется автоматически после объявления самого пространства имен. Так что, в итоге, код построится таким образом:
Рассмотрим пример работы с безымянным пространством имен:
В заключение, следует отметить, что безымянные пространства носят локальный характер и могут быть использованы только в том файле, в котором они объявлены.
Экзаменационные задания. Для реализации всех заданий использовать ООП. Реализация карточной игры - "Покер". Написать программу, которая разгадывает японский кроссворд под названием "Судоку". Пользователь вводит начальные значения уже существующие в кроссворде, который необходимо разгадать, и программа выдает на экран готовый результат. Написать программу, реализующую электронный органайзер. Реализовать возможности добавления, удаления, редактирования и хранения данных. Предусмотреть обработку всех возможных ошибок.
Домашнее задание Написать функцию вычисления значения по заданной строке символов, являющихся записью этого числа в десятичной системе счисления. Предусмотреть случай выхода за границы диапазона определяемого типом int. Используйте механизм исключений. Перепишите класс stack одного из предыдущих домашних заданий таким образом, чтобы генерировать исключения для такого количества условий, какое Вы считаете приемлемым. (Например, невозможность выделить нужное количество памяти, переполнение стека и т.д.)
Урок №34.
Преобразование типов в стиле С++. Для начала напомним, что оператор приведения типов позволяет компилятору преобразовывать один тип данных в другой. И язык программирования С, и язык программирования С++ поддерживают такую форму записи приведения типа:
Операторы приведения типа в языке С++. Кроме стандартной формы в стиле С, язык С++ поддерживает дополнительные операторы приведения типа: Const_cast
Dynamic_cast
Reinterpret_cast
Static_cast
Рассмотрим данные конструкции более детально: const_cast используется для явного переопределения модификаторов const и/или volatile. Новый тип должен совпадать с исходным типом, за исключением изменения его атрибутов const или volatile. Чаще всего оператор const_cast используется для снятия атрибута const. Например: Примечание:Следует помнить, что только оператор const_cast может освободить от "обета постоянства", т.е. ни один из остальных операторов этой группы не может "снять" с объекта атрибут const.
Примечание:Кстати, стоит упомянуть о том, что такое volatile!!! Данный модификатор даёт компилятору понять, что значение переменной, может быть изменено неявным образом. Например, есть некая глобальная переменная, её адрес передаётся встроенному таймеру операционной системы. В дальнейшем эта конструкция может использоваться для отсчёта реального времени. Естественно, что значение этой переменной изменяется автоматически без участия операторов присваивания. Так вот такая переменная должна быть объявлена с использованием ключевого слова volatile. Это связано с тем, что многие компиляторы не обнаружив ни одного изменения переменной с помощью какого-либо присваивания, считают, что она не изменяется и оптимизируют выражения с ней, подставляя на её место конкретное значение. При этом компилятор переменную не перепроверяет. Действительно, зачем, если переменная для него имеет характер "неизменяемой"?! volatile - будет блокировать подобные действия компиляторов. dynamic_cast проверяет законность выполнения заданной операции приведения типа. Если такую операцию выполнить нельзя, то выражение устанавливается равным нулю. Этот оператор в основном используется для полиморфных типов. Например, если даны два полиморфных класса, B и D, причем класс D выведен из класса B, то оператор dynamic_cast всегда может преобразовать указатель D* в указатель B*. Оператор dynamic_cast может преобразовать указатель B* в указатель D* только в том случае, если адресуемым объектом является объект D. И вообще, оператор dynamic_cast будет успешно выполнен только при условии, что разрешено полиморфное приведение типов (т.е. если новый тип можно законно применять к типу объекта, который подвергается этой операции). Рассмотрим пример, демонстрирующий всё вышесказанное:
static_cast выполняет неполиморфное приведение типов. Его можно использовать для любого стандартного преобразования. При этом никакие проверки во время работы программы не выполняются. Фактически, static_cast - это аналог стандартной операции преобразования в стиле С. Например, так:
reinterpret_cast переводит один тип в совершенно другой. Например, его можно использовать для перевода указателя в целый тип и наоборот. Оператор reinterpret_cast следует использовать для перевода типов указателей, которые несовместимы по своей природе. Рассмотрим пример:
Итак, мы познакомились с преобразованиями в стиле C++. Вполне очевидны положительные стороны этих новых способов. Во-первых данные преобразования позволяют сделать то, чего стандарт языка С даже не предполагал: снять модификатор const, или радикально поменять тип данных. Во-вторых, стиль С++ увеличивает контроль над преобразованиями и позволяет выявить ошибки с ними связанные на ранних этапах.
Стандартная библиотека шаблонов (STL) и её основные понятия (контейнер, итератор, алгоритм, функтор, предикат, аллокатор). На сегодняшний день, почти все компиляторы языка C++ содержат специальную встроенную библиотеку STL. Данная библиотека содержит набор классов и функций, которые представляют собой реализацию часто используемых алгоритмов. А поскольку, библиотека предназначена для работы с различными типами данных, все классы и функции в ней являются шаблонными. Детальным рассмотрением этого замечательного средства мы и займемся в ближайшее время. Для того чтобы разобраться с библиотекой STL, нам необходимо познакомиться с основными понятиями, на которых она базируется. Итак. Приступим. Наша библиотека включает в себя четыре компонента, составляющие её внутреннюю структуру:
Кроме вышеописанных конструкций, в STL поддерживаются еще некоторые встроенные компоненты:
В данной части урока мы рассмотрели лишь основные определения, касаемые STL. Далее, мы будем анализировать каждый из этих механизмов отдельно.
Класс auto_ptr. В языке программирования С++ есть понятие, которое проявляется в следующем утверждении - "выделение ресурса - это инициализация". Данное утверждение идеально используется при выделении абсолютно любого типа ресурсов. Это делает работу программы более надежной, особенно, если в ходе работы программы возможно возникновение исключений. Например, программа открывает некий файл или выделяет фрагмент памяти. При завершении работы этой программы естественно необходимо закрыть файл или освободить память. Однако исключительная ситуация может проявиться еще до того, как будет выполнено одно из вышеописанных действий, в результате чего действие так и не выполнится.
Решением данной проблемы является следующий набор действий:
А, теперь главное - В случае возникновения исключительной ситуации при работе программы объект будет естественно уничтожен, но при этом для него будет вызван его деструктор, который и закроет файл (освободив память). Если же, программа завершится корректно, то и в этом случае вам не придется думать о явном закрытии файла, так как созданный объект будет автоматически уничтожен при выходе из области видимости и файл будет закрыт опять таки деструктором класса.
Для усовершенствования нашего принципа мы можем использовать класс auto_ptr (automatic pointer - автоматический указатель). Данный класс предоставляется стандартной библиотекой С++ и предназначен для работы с объектами, которые обычно необходимо удалять явно (например, объекты, созданные динамически с помощью оператора new). для создания объекта класса auto_ptr параметром конструктора должен быть указатель на объект, созданный динамически. Дальше c auto_ptr можно работать почти как с обычным указателем, который указывает на тот же динамический объект, на который указывал исходный указатель. Нам не нужно думать о явном удалении объекта, он будет автоматически удален деструктором класса auto_ptr. Синтаксис класса auto_ptr в стандартной библиотеке выглядит так:
Примечание:Кроме переопределения операторов -> и *, класс auto_ptr содержит две функции-члена: Теперь, вполне естественно, рассмотрев общую конструкцию auto_ptr, полюбопытствовать, как он выглядит в работе:
©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|