Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Двухфазное конструирование

From Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Two-phase construction
Den123
Последнее редактирование: hamishwillee (09 Dec 2011)

Contents

Краткое описание

В C++ программировании под Symbian ОС концепция двухфазного конструирования используется для того чтобы гарантировано избежать сброса(leave) при создании и инициализации объектов перед тем, как поместить их в стек очистки (cleanup stack).

Причины возникновения проблемы

В C++ программировании под Symbian ОС указатели на объекты в динамической памяти сохраняются в стеке очистки. Это позволяет автоматически уничтожать объекты в случае возникновения сброса(leave). Вновь созданный объект помещается в стек очистки сразу же после создания и инициализации его с помощью конструктора. Согласно правилу, принятому в C++, после выделения памяти для объекта и до завершения выполнения конструктора объект не может быть сохранен в стеке очистки - вот почему возникновение сброса(leave) в это время недопустимо.

Решение проблемы и его последствия

Для того чтобы предотвратить возникновение исключительной ситуации до того, как объект помещен в стек очистки, нужно предотвратить возникновение исключения в конструкторе. Этого можно достигнуть, если реализовать двухфазный конструктор. Согласно концепции двухфазного конструирования, весь код, который может привести к сбросу, а так же все вызовы функций, который могут выбросить исключения выносят из конструктора в отдельный метод ConstructL() - он и является второй фазой конструирования. (Если предок содержит свой собственный метод ConstructL() - он должен быть явно вызван во время второй фазы конструирования объекта.) Вызов ConstructL() производится после создания объекта и помещения его в стек очистки. Для часто используемых классов вызов обычного конструктора и метода ConstructL() объединяют в одну специальную статическую функцию NewL(). Соответственно, для создания объекта нужно пользоваться этой функцией-фабрикой. Алгоритм работы этой функции следующий:

  • выделить память под объект
  • поместить его в стек очистки
  • выполнить вторую фазу конструирования (вызвать ConstructL())
  • извлечь созданный и проинициализированный объект из стека очистки

Если подразумевается дальнейшее использование вновь созданного объекта как локального (то есть он должен находится в стеке очистки все свое время жизни) реализуется дополнительная статическая функция NewLC() - алгоритм ее работы такой же как и у NewL() за одним исключением - вновь созданный объект не извлекается из стека очистки. Пример реализации ConstructL(), NewL(), NewLC():

	// Фаза #1 
CMyClass::CMyClass()
{
}
 
// Фаза #2
void CMyClass::ConstructL()
{
// Инициализация членов-данных
}
 
// Обе фазы создания вместе ...
CMyClass * CMyClass::NewL()
{
CMyClass * self = new (ELeave) CMyClass();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
 
CMyClass * CMyClass::NewLC()
{
CMyClass * self = new (ELeave) CMyClass();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}

В будущем...

Строго говоря, нет необходимости поддерживать двухфазное конструирование и стек очистки после того, как в Symbian появилась поддержка стандартных возможностей C++ и реализация сбросов(leaves) была переделана на обычные исключения. Exception/Leave - защищенный код гораздо проще реализовать в стандартном C++, однако Symbian продолжает поддерживать старый вариант реализации в целях совместимости. Когда-нибудь в будущем (будем надеется недалеком) мы сможем забыть эту изжившую себя концепцию и использовать стандартный C++ для разработки ПО под Symbian ОС.

This page was last modified on 9 December 2011, at 00:57.
178 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×