На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> ошибка в логике , не могу найти
    Здрасте! :D Не могу понять где я ошибся :gamer:
    ExpandedWrap disabled
      #include <iostream>
      #include <vector>
       
      class Container;
       
      class Object
      {  
      public:
          Object(Container* pParent)
              : m_pCont(pParent)
              , m_CheckState(csNo) {}
          enum CheckState { csNo, csYes, csComp };    
          CheckState getCheckState() const { return m_CheckState;}
          void setCheckState(CheckState cs) { m_CheckState = cs;}
          void someOperation();
      private:
          CheckState m_CheckState;
          Container* m_pCont;
      };
       
       
      class Container
      {
          typedef std::vector<Object> vecobj_t;
          typedef vecobj_t::size_type size_type;
      public:    
          int getCountChecked() const;
          void setCheckRandom();
          size_type getCountObjects() const { return m_Objects.size();}
          void addObject(const Object& ob) { m_Objects.push_back(ob);}
          const Object& operator[](int i) const { return m_Objects[i];}
      private:    
          std::vector<Object> m_Objects;
      }; :wall:
       
      void Object::someOperation()
      {
          if (getCheckState() == csNo)
              setCheckState(csYes);
       
          if (m_pCont->getCountChecked() != m_pCont->getCountObjects())
              m_pCont->setCheckRandom();
      }
       
       
      int Container::getCountChecked() const
      {
          int cnt=0;
          for(size_type i=0; i < getCountObjects(); ++i)  
          {
              if (m_Objects[i].getCheckState() != Object::csNo)
                  cnt++;
          }  
       
          return cnt;
      }
       
      void Container::setCheckRandom()
      {
          while (true)  
          {      
              int i = rand() % getCountObjects();            
       
              if (m_Objects[i].getCheckState() != Object::csNo)
                  continue;
       
              m_Objects[i].setCheckState(Object::csComp);
              break;  
          }  
      }
       
      int _tmain(int argc, _TCHAR* argv[])
      {
          Container cont;
          Object o1(&cont);
          Object o2(&cont);
          Object o3(&cont);
       
          cont.addObject(o1);
          cont.addObject(o2);
          cont.addObject(o3);
       
          o1.someOperation();
       
          for (int i=0; i < cont.getCountObjects(); ++i)
          {
              if (cont[i].getCheckState() == Object::csYes)
                  std::cout << "Yes" << std::endl;
       
              if (cont[i].getCheckState() == Object::csComp)
                  std::cout << "Comp" << std::endl;
          }
       
          return 0;
      }

    Выводит только Comp, а по логике должно быть Yes и Comp.
    Где ошибка? :wacko: :gamer::gamer:
    Сообщение отредактировано: Cfon -
      Код, конечно веселый. А ошибка в том что в контейнере у тебя сохраняется копия объекта, а изменяешь ты оригинал
        Цитата Олег М @
        Код, конечно веселый. А ошибка в том что в контейнере у тебя сохраняется копия объекта, а изменяешь ты оригинал

        Спс! Как же я затупил! Точно в кониейнере копия же! :fool:
          поменял на shared_ptr теперь все пучком :writer:

          ExpandedWrap disabled
            class Container
            {      
                typedef std::vector<std::shared_ptr<Object>> vecobj_t;  
                typedef vecobj_t::size_type size_type;
            public:    
                int getCountChecked() const;
                void setCheckRandom();
                size_type getCountObjects() const { return m_Objects.size();}
                void addObject(std::shared_ptr<Object> ob) { m_Objects.push_back(ob);}
                const Object& operator[](int i) const { return *m_Objects[i];}
            private:        
                vecobj_t m_Objects;
            };
            А что ты вообще пытаешься сделать?
            Сообщение отредактировано: Олег М -
              Цитата Олег М @
              А что ты вообще пытаешься сделать?

              да так изучаю то сё :D
                Понятно. Рекомендую тебе в addobject делать emplace_black(move(……… .
                  Цитата Олег М @
                  Понятно. Рекомендую тебе в addobject делать emplace_black(move(……… .

                  сделал m_Objects.emplace_back(std::move(ob)) :)
                  я так понял что данный прием оптимизирует STL код, путем минимизации копирующих операций?
                    Примерно так. Только он вообще не использует в этом случае копирование. Почитай про move–конструкторы. Очень полезная штука.
                      раньше читал, но надо освежить знания, про все эти фишки С++11/14: перемещающие операции, идеальную передачу параметров, переменные шаблоны и тд :writer:
                        В первую очередь обрати внимание на эти конструкторы и на универасальные ссылки, std::forward
                          ok :)
                          кстати обнаружил что emplace_back реализуется через push_back, думаю в моем случае push_back(std::move(ob)) имеет тот же эффект?
                            Не стоит. А какой ты компилятор используешь?

                            Добавлено
                            Кстати, в случае с вектором такая реализация emplace-back вполне возможна. В случае же списком – не вижу смысла.

                            Добавлено
                            Хотя, и там тоже не вижу
                              Цитата Олег М @
                              Не стоит. А какой ты компилятор используешь?

                              Visual Studio 2010 :)
                                Цитата Cfon @
                                кстати обнаружил что emplace_back реализуется через push_back, думаю в моем случае push_back(std::move(ob)) имеет тот же эффект?

                                Точно, в 11 стандарте появилась декларация void push_back (value_type&& val); Не обращал внимания, всегда пользовался emplace_back. Значит да, в твоём случае наверное без разницы.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0696 ]   [ 17 queries used ]   [ Generated: 7.05.24, 01:16 GMT ]