Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.180.32] |
|
Сообщ.
#1
,
|
|
|
Есть класс типа фабрика. При регистрации классов всё нормально, а вот при создании вектор m_Patern оказывается пустым, при этом поле m_GenId сохраняет своё значение. Не подскажите в чём дело? Стандарт 2003.
class TInitTSourcesFunctor { public: TInitTSourcesFunctor() { TCreatorTran<TDG_TIME_COMPLEX, std::complex<double> >::Registration( new TBaseTransformationPatern<TDG_TIME_COMPLEX, TSourcesFunctor, int, std::complex<double> >); } }; static TInitTSourcesFunctor init; template <TTypeDataOut TType, class TD> class TCreatorTran { public: const TTypeDataOut Type; public: TCreatorTran(): Type(TType) { m_GenId += 0; } static unsigned GenId() { return ++m_GenId; } static void Registration(TBaseTransformation* a_T) { a_T->setId(GenId()); m_Patern.push_back(a_T); } static TBaseTransformation* Create(unsigned a_Id) { std::vector<TBaseTransformation*>::iterator it = m_Patern.begin(); for (; it != m_Patern.end(); ++it) { if ((*it)->Id() == a_Id) return (*it)->Create(); } return NULL; } static std::string ChildName(unsigned a_Id) { std::string str; std::vector<TBaseTransformation*>::iterator it = m_Patern.begin(); for (; it != m_Patern.end(); ++it) { if ((*it)->Id() == a_Id) return (*it)->Name(); } return str; } static unsigned MaxId() { return m_GenId; } private: TCreatorTran(const TCreatorTran &a_V); TCreatorTran& operator = (const TCreatorTran &a_V); private: static unsigned m_GenId; static std::vector<TBaseTransformation*> m_Patern; }; |
Сообщ.
#2
,
|
|
|
По этим обрывкам наверняка сказать ничего нельзя. Предположу, что проблема в порядке инициализации статических объектов: порядок инициализации в пределах одной единицы трансляции определяется порядком определений объектов, порядок инициализации в разных единицах трансляции неопределён.
Похоже, что сначала инициализируется init, который вызывает TCreatorTran<>::Registration(), которая делает std::vector<>::push_back(), который чудесным образом не валит приложение в эксепшн на использовании неинициализированного объекта, и только потом отрабатывает конструктор по умолчанию(?) этого вектора TCreatorTran<>::m_Patern, который благополучно инициализирует объект, как и положено, пустым. Добавлено P.S. Т.к. TCreatorTran<> суть шаблон, то если он не инстаницирован явно, он и его статические элементы будут конкретизированы и инстанцированы неявно в точке инстанцирования. Таковая в подобной ситуации всегда будет после определения экземпляра TInitTSourcesFunctor, потому что только тут (?) впервые используется TCreatorTran<> с конкретными шаблонными аргументами. |
Сообщ.
#3
,
|
|
|
Спасибо, забыл что порядок создания статических объектов не определён.
|