Листинг 13.15. Управляемая инициализация статических объектов
// — -- модуль Firstclass.h // от этого класса (Firstclass) зависит второй (Secondclass) #ifndef _FIRST #define _FIRST class Firstclass{ unsigned int Year; public:
FirstclassO ; void print(void)const; };
#endif //-- модуль Secondclass.h // этот класс (Secondclass) зависит от первого (Firstclass) #ifndef ^SECOND #define _SEC0ND #include "Firstclass.h" class Secondclass { Firstclass t; // вот зависимость от порядка инициализации public:
Secondclass(const Firstclass& x); void print(void)const; };
#endif // модуль implementation.cpp #include<iostream> // реализация класса Firstclass#include "Firstclass.h"
Firstclass::FirstclassO:Year(2900) // инициализация по умолчанию { std::cout << "Firstclass constructor " << Year << std::endl; }void Firstclass::print(void)const { std::cout << "Firstclass " << Year << std::endl: } // реализация класса Secondclass#include "Secondclass.h"
Secondclass::Secondclass(const Firstclass& x):t(x) { std::cout << "Secondclass "; printO; }void Secondclass: :print(void)const { t.printO; } // модуль Fi rstC lass Function. cpp #include "Firstclass.h" Firstclass& dl(void) { static Firstclass d; // статический объект return d; // возврат ссылки на него } // - модуль SecondCla^sFunction.cpp #include "Firstclass.h" #include "Secondclass.h"
Листинг 13.15 (продолжение)
Firstclass& dl(void); Secondclass& d2() { static Secondclass d(dl()); // статический объект return d; // возврат ссылки на него } // модуль main.cpp #include<iostream>#include "Firstclass.h" #include "Secondclass.h" // моделирует неверный порядок инициализации
extern Firstclass ddl;
Secondclass dd2(ddl);
Firstclass ddl; // правильная инициализация
Secondclass& d2(); int main() { d2(); // гарантирует правипьный порядок инициапизации return 0; }
Проект включает 5 модулей: файлы с определениями классов Firstclass.h и Second-class.h, файл implementation.срр с реализацией обоих классов, файлы Firstclass-Function.cpp и SecondclassFunction.cpp с определениями функций и файл main.cpp, в котором указан порядок инициализации. В файлах implementation.срр, First-classFunction.cpp и SecondclassFunction.cpp для наглядности подключаются оба файла-заголовка. Если бы в файле Secondclass.h не был прописан страж, это привело бы к повторному определению класса Fi rstclass. В принципе достаточно подключать только Secondclass.h — тогда стража можно убрать.
Зависимость от порядка инициализации проявляется в том, что объект типа Secondclass должен инициализироваться объектом Firstclass. Поэтому объект типа Fi rstclass должен быть уже проинициализирован к моменту определения объекта типа Secondclass. Для наглядности в главной программе моделируется неправильный порядок инициализации — глобальные объекты определяются в обратном порядке. В результате на экран выводятся следующие строки:
Это означает, что в момент определения объекта dd2 типа Secondclass объект
ddl типа FirastclassHe был проинициализирован — конструктор для создания
ddl вызван после конструктора, создающего dd2. Подчеркнем, что такая ситуация может сложиться, если глобальные объекты зависимых классов определяются в разных модулях. ,
Вместо явного определения объектов мы реализовали функции. Функция dl() реализует определение объекта типа Firstclass,а функция d 2 () — определение объекта типа Secondclass. Сами объекты объявлены в функциях как статические, следовательно, время жизни их совпадает с временем жизни глобальных объектов. В функции d2(), реализующей определение объекта типа Secondclass, мы и управляем зависимостью, передавая конструктору в качестве аргумента вызов функции dl(), которая возвращает ссылку на статический объект. В главной функции мы в нужном месте просто прописываем вызов функции d2 (), создающей объект типа Secondclass. В результате на экран выводятся строки:
Это и означает, что конструкторы вызываются в правильном порядке.
Еще раз подчеркнем, что все описанное касается ситуации, когда глобальные объекты зависимых классов определяются в разных модулях. Стандарт не гарантирует правильного порядка инициализации таких объектов, поэтому мы должны этим явно управлять.
Опубликовал Kest
January 30 2014 23:35:27 ·
0 Комментариев ·
3596 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.