На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
  
> обнуление статического вектора члена класса
    Есть класс типа фабрика. При регистрации классов всё нормально, а вот при создании вектор m_Patern оказывается пустым, при этом поле m_GenId сохраняет своё значение. Не подскажите в чём дело? Стандарт 2003.
    ExpandedWrap disabled
      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;


    ExpandedWrap disabled
      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;
      };
      По этим обрывкам наверняка сказать ничего нельзя. Предположу, что проблема в порядке инициализации статических объектов: порядок инициализации в пределах одной единицы трансляции определяется порядком определений объектов, порядок инициализации в разных единицах трансляции неопределён.
      Похоже, что сначала инициализируется init, который вызывает TCreatorTran<>::Registration(), которая делает std::vector<>::push_back(), который чудесным образом не валит приложение в эксепшн на использовании неинициализированного объекта, и только потом отрабатывает конструктор по умолчанию(?) этого вектора TCreatorTran<>::m_Patern, который благополучно инициализирует объект, как и положено, пустым.

      Добавлено
      P.S. Т.к. TCreatorTran<> суть шаблон, то если он не инстаницирован явно, он и его статические элементы будут конкретизированы и инстанцированы неявно в точке инстанцирования. Таковая в подобной ситуации всегда будет после определения экземпляра TInitTSourcesFunctor, потому что только тут (?) впервые используется TCreatorTran<> с конкретными шаблонными аргументами.
        Спасибо, забыл что порядок создания статических объектов не определён.
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0290 ]   [ 16 queries used ]   [ Generated: 19.04.24, 22:51 GMT ]