Проблемы, связанные с глобальными объектами
Проблемы, связанные с глобальными объектами
При разработке больших проектов, часто возникает необходимость обращаться из одного модуля программы к объектам, существующим в другом модуле. Такие объекты, как правило, существуют в единичных экземплярах, поэтому наиболее распространенной практикой является создание глобальных объектов данного типа и ссылка на них из других модулей программы с применением ключевого слова extern. Так, например, при создании ATL проекта в среде MSVC++, мастер проекта создает экземпляр класса – наследника от CComModule, _Module, в главном файле проекта, и помещает объявление extern CMyModule _Module в stdafx.h, что делает доступным объект _Module из других файлов проекта. Однако при таком подходе отсутствует механизм, предотвращающий создание нескольких объектов данного типа. Кроме того, поскольку объект создается статически, отсутствует возможность управлять процессом его создания. То есть, объект создается автоматически, до момента его фактического применения в программе. Это может приводить к некоторым неприятным последствиям: если объект работает с некоторой инфраструктурой, то инициализация и освобождение этой инфраструктуры должны быть помещены, например, в этот же класс.
листинг 1
class BusinesLogic //использует инфраструктуру COM
{
public:
BusinesLogic () {
CoInitializeEx(NULL, COINIT_MULTITHREADED);
//некая работа с COM
}
~BusinesLogic () {
CoUninitialize();
}
};
Глядя на следующий фрагмент, нельзя сказать, была ли инициализирована инфраструктура, а если да, то ничего нельзя сказать о выбранной потоковой модели COM. Как следствие, такой код – источник ошибок и возможных проблем с их диагностикой.
листинг 2
BusinesLogic BL;
void main() {
HRESULT hr;
IUnknown *p;
hr=CoCreateInstance(CLSID_AppartmentThreadClass, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&p);
}
При наличии в программе двух глобальных объектов, ссылающихся друг на друга, помещенных в разных модулях, может возникнуть ситуация, при которой один объект попытается обратиться к другому, еще не созданному объекту.
Выходом является использование паттерна проектирования Singleton. Его особенностью является то, что он гарантирует существование объекта в единственном экземпляре, а самое главное, то, что он создается в тот момент, когда это требуется клиенту. Последующие попытки конструирования объекта приводят лишь к возвращению клиенту ссылки на уже существующий объект, но не к созданию нового. Вот пример класса, реализующего логику паттерна Singleton:
Листинг 3
class Singleton {
static Singleton* _self;
protected:
Singleton(){}
public:
static Singleton* Instance() {
if (!_self) _self = new Singleton();
return _self;
}
//методы
void aFunc1();
void aFunc2();
//данные
int aData;
};
Singleton* Singleton::_self=NULL;
ПРИМЕЧАНИЕ Конструктор класса объявлен в защищенной секции. Благодаря этому отсутствует возможность создавать объекты класса по оператору new или статически. Вместо этого для конструирования объекта служит метод Instance(), который гарантирует, что в программе будет существовать только один экземпляр данного класса.
Таким образом, класс Singleton инкапсулирует в себе методы и свойства данной сущности, может быть доступен из любого места программы благодаря методу Instance(), а, кроме того, теперь мы можем управлять временем жизни этого объекта. Вот пример использования класса Singleton:
Модуль MAIN
#include "app.h"
void main() {
Application* application = Application::Instance();
application->Run();
delete application;
}
Модуль APP
#include <string>
using std::string;
class Window;
class Application {
static Application* _self;
Window *wnd;
protected:
Application(){}
public:
static Application* Instance();
int loadIniInt(string& section, string& var);
void saveIniInt(string& section, string& var, int val);
void Run();
};
Application* Application::Instance() {
if(!_self) _self = new Application();
return _self;
}
int Application::loadIniInt(string& section, string& var) {
printf("loadIni ");
return 100;
}
void Application::saveIniInt(string& section, string& var, int val) {
printf("saveIni ");
}
void Application::Run() {
wnd=new Window();
//цикл обработки сообщений
delete wnd;
}
Application* Application::_self=NULL;
Модуль WINDOW
#include "app.h"
class Window {
int width;
int height;
public:
Window() {
Application *p=Application::Instance();
p->loadIniInt(string("Window"), string("width"));
p->loadIniInt(string("Window"), string("height"));
}
~Window() {
Application *p=Application::Instance();
p->saveIniInt(string("Window"), string("width"), width);
p->saveIniInt(string("Window"),string("height"), height);
}
};
Этот листинг показывает, как можно организовать каркас оконного приложения, используя паттерн Singleton. Из класса окна требуется доступ к некоторым функциям объекта Application. Поскольку объект приложения существует всегда в одном экземпляре, то он реализует паттерн Singleton, а доступ к объекту приложения из объекта окна осуществляется благодаря методу Instance().
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Из PHP в Excel: работа с COM-объектами
Из PHP в Excel: работа с COM-объектами Данная серия статей посвящена созданию документов Excel при помощи PHP. Данная возможнось может понадобиться, например, если нужно предоставить пользователю загружаемые данные в виде листов Excel. Это могут быть прайсы на продукцию,
12.1 ПРОБЛЕМЫ, СВЯЗАННЫЕ С МНОГОПРОЦЕССОРНЫМИ СИСТЕМАМИ
12.1 ПРОБЛЕМЫ, СВЯЗАННЫЕ С МНОГОПРОЦЕССОРНЫМИ СИСТЕМАМИ В главе 2 мы говорили о том, что защита целостности структур данных ядра системы UNIX обеспечивается двумя способами: ядро не может выгрузить один процесс и переключиться на контекст другого, если работа производится в
4.4. Проблемы, связанные с использованием отсечения
4.4. Проблемы, связанные с использованием отсечения Мы уже убедились в том, что иногда необходимо учитывать стратегию, используемую в Прологе для поиска в базе данных, и что порядок записи утверждений в программе на Прологе влияет на результат доказательства
Глава 11 Работа с объектами
Глава 11 Работа с объектами Теперь, когда мы научились создавать объекты Adobe InDesign, поговорим о том, что с ними делать. Этот разговор вынесен в отдельную главу по очень простой причине: все операции по перемещению, трансформации, копированию выполняются, по сути, одинаково
Знакомство с объектами Range
Знакомство с объектами Range Если вы редактируете документ самостоятельно, вы должны поместить указатель мыши в нужное место либо выделить определенный фрагмент, прежде чем добавлять, удалять или форматировать текст. Однако в Word объекты Range избавляют вас от подобной
6.4. Проблемы, связанные с блокировками
6.4. Проблемы, связанные с блокировками В этом разделе мы рассмотрим только внутренние блокировки, используемые сервером MySQL при совместной работе нескольких потоков с одними и теми же данными, и не коснемся внешних блокировок, обеспечивающих координацию работы сервера
Работа с MBV-объектами
Работа с MBV-объектами Наши первые приложения удаленного взаимодействия позволяли доступ клиентов к одному WKO-типу. Напомним, что WKO-типы (по определению) являются MBR-типами, поэтому доступ клиента к ним осуществляется через агента-посредника. В противоположность этому,
Работа с объектами команд
Работа с объектами команд Теперь, когда вы понимаете роль объекта соединения, мы выясним, как предъявить SQL-запрос базе данных. Тип SqlCommand (который получается из DbCommand) является объектом представлением SQL-запроса, имени таблицы или хранимой процедуры. Вид соответствующей
Операции с объектами
Операции с объектами Взглянем еще раз на нашу будущую визитку. Вы увидите, что каждый ее отдельный элемент заключен в пунктирную рамочку. А если вы щелкнете по нему, то на линиях рамки проявятся кружочки – по углам и в центре каждой линии. Эти рамки нужны лишь для того,
Действия с созданными объектами
Действия с созданными объектами К основным операциям с объектами относятся изменение размеров и свойств, удаление, копирование, вырезание, упорядочивание и др.Пропорциональное изменение размера объекта1. Выделить объект инструментом Выбрать.2. Прижать маркер к
Что происходит с объектами
Что происходит с объектами ОО-программа создает объекты. Предыдущая лекция показала, как полезно полагаться на динамическое создание для получения гибких объектных структур, подстраивающихся автоматически к нуждам
Работа с объектами и их экземплярами
Работа с объектами и их экземплярами Перед тем как начать работу с экземпляром какого-либо объекта, его нужно создать. Создание экземпляра объекта выполняется с помощью оператора new: <Переменная> = new <Имя объекта>([<Список параметров, разделенных запятыми>]) После
5.2.3. Действия с объектами Numbers
5.2.3. Действия с объектами Numbers В этом разделе перечислим основные действия с объектами электронной таблицы, а также рассмотрим работу с пиктограммами листов и таблиц, расположенными на панели Sheets (Листы).Действия с ячейкамиК действиям над ячейками относятся:
5.3.3. Действия с объектами на слайде
5.3.3. Действия с объектами на слайде Keynote, как и Pages, предоставляет нам возможность выполнять следующие действия с объектами: изменение размера, перемещение, копирование, зеркальное отображение, поворот, группировка, блокировка, выравнивание, распределение, перемещение
6.3.6. Управляем объектами
6.3.6. Управляем объектами Для выполнения заданий нам понадобится материал разд. 5.3.3.Вспомним, какие действия будут происходить на слайде.? Звук начинает проигрываться с самого начала С самого же начала появляется текст с фоном.? Затем при чтении слова «Ивашка» появляется