Шаблон Синглетон (Singleton pattern)
Одним из применений статических членов является конструкция под названием Singleton pattern. Данная конструкция позволяет создавать только один экземпляр класса, и обеспечивает глобальный доступ к этому экземпляру. Иногда бывает очень важно, чтобы класс мог создать только один экземпляр (объект). Например, система может иметь несколько принтеров, но должен быть только один спулер принтера. Как мы можем гарантировать, что имеется только один экземпляр класса, и что этот экземпляр доступен?! Можно, например, объявить глобальную переменную. Однако, данный способ плох тем, что мы во-первых засоряем пространство имен, а во-вторых не можем предотвратить создание нескольких экземпляров класса. Лучшим решением будет класс, который сам отслеживает создание экземпляров и доступ к единственному объекту. Мы можем сделать так, чтобы класс гарантировал, что никакой другой экземпляр не может быть создан. Надо написать класс, у которого можно создать только один экземпляр, но этим экземпляром должны пользоваться объекты других классов. Вот, пожалуй, самая простая из схем, реализующих эту задачу.
Комментарии к примеру. Класс Singleton окончательный — его нельзя расширить. Его конструктор закрытый — никакой метод не может создать экземпляр этого класса. Единственный экземпляр s класса Singleton — статический, он создается внутри класса. Однако можно получить указатель на этот экземпляр методом getReference(), изменить состояние экземпляра s методом setValue() или просмотреть его текущее состояние методом getValue(). Безусловно, это только схема — класс Singleton надо еще наполнить полезным содержимым, но идея выражена ясно и полностью.
Домашнее задание Создайте класс Время, в котором реализованы операции сложения, вычитания, сравнения, ввода и вывод на экран. Возможность конвертации времени из американского формата am (pm): 10:00 pm = 22:00, 12:00 pm =00:00 Создать класс для работы с матрицами. Предусмотреть, как минимум, функции для сложения матриц, умножения матриц, транспонирования матриц, присваивания матриц друг другу, установка и получение произвольного элемента матрицы. Необходимо перегрузить соответствующие операторы.
Урок №25.
Перегрузка оператора -> Мы надеемся, что вы помните, что в C++ можно перегрузить почти все операторы, за исключением нескольких. Во всяком случае, оператор -> перегружается, и это имеет значение крайне важное. Кстати, этот оператор называется селектором (member selector). Рассмотрим пример:
Итак, обсудим результат: У нас есть класс Temp, который может иметь экземпляры, обладает некоторым членом TEMP и минимальным набором функций для работы с ним. Кроме того, мы создали класс объекта-указателя MyPtr, в котором храним обычный указатель, но доступ к нему ограничиваем, и перегружаем для него операторы:
Рассмотрим положительные моменты - мы получили класс объектов-указателей, которые можно смело применять вместо настоящих. Это удобно, т.к. все функции для работы с указателем можно инкапсулировать в этом классе. Однако есть еще одно широко распространенное применение данной конструкции, с которым мы с вами познакомимся в следующем разделе урока. Вперед!
Понятие "умного" указателя (smart pointer) Начнем с того, что то, о чём мы с Вами сейчас будем говорить, реализуется с помощью перегрузки селектора. Итак. Умный указатель (англ. smart pointer) — класс, имитирующий интерфейс обычного указателя и добавляющий к нему некую новую функциональность, например проверку границ при доступе или очистку памяти. Иначе говоря, умные указатели - это объекты, в которых хранится указатель на настоящий объект и, как правило, счётчик числа обращений к объекту. В классе также присутствует деструктор для настоящего объекта, который не вызывается извне, а только внутри smart pointer. Принцип таков, что, когда счётчик обращений к объекту равен 0, вызовется деструктор. Например, есть массив указателей на объекты. Вы используете копию указателя на один объект где-нибудь ещё. Потом очищаете массив, удаляя при этом объекты, а "где-нибудь ещё" все ещё хранит указатель. Естественно, что, при доступе к нему происходит сбой программы, т.к. объект был удалён при очистке массива. При наличии smart pointer, такого не произойдёт, т.к. при создании копии указателя внутренний счётчик увеличится на 1. Те будет равен двум - 1 для массива, и ещё 1 для копии. Теперь даже если мы удалим объект из массива, внутренний счётчик уменьшится на 1 и станет равным 1, т.е. копия может продолжать работать с объектом. После того как он станет ненужным, копия освобождает память от него и счётчик становится равным 0. Именно, в этот момент вызывается деструктор для оригинального объекта. Ну что ж, всё сказано. Пора попробовать блюдо под названием "умный указатель" на вкус. :)))
Сейчас, мы создали свой собственный указатель, в последующих уроках, нами будет рассмотрен уже готовый smart poiter из библиотеки STL, под названием auto_ptr.
©2015 arhivinfo.ru Все права принадлежат авторам размещенных материалов.
|