Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.190.152.38] |
|
Сообщ.
#1
,
|
|
|
Здрасте! Не могу понять где я ошибся
#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. Где ошибка? |
Сообщ.
#2
,
|
|
|
Код, конечно веселый. А ошибка в том что в контейнере у тебя сохраняется копия объекта, а изменяешь ты оригинал
|
Сообщ.
#3
,
|
|
|
Цитата Олег М @ Код, конечно веселый. А ошибка в том что в контейнере у тебя сохраняется копия объекта, а изменяешь ты оригинал Спс! Как же я затупил! Точно в кониейнере копия же! |
Сообщ.
#4
,
|
|
|
поменял на shared_ptr теперь все пучком
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; }; |
Сообщ.
#5
,
|
|
|
А что ты вообще пытаешься сделать?
|
Сообщ.
#6
,
|
|
|
Цитата Олег М @ А что ты вообще пытаешься сделать? да так изучаю то сё |
Сообщ.
#7
,
|
|
|
Понятно. Рекомендую тебе в addobject делать emplace_black(move(……… .
|
Сообщ.
#8
,
|
|
|
Цитата Олег М @ Понятно. Рекомендую тебе в addobject делать emplace_black(move(……… . сделал m_Objects.emplace_back(std::move(ob)) я так понял что данный прием оптимизирует STL код, путем минимизации копирующих операций? |
Сообщ.
#9
,
|
|
|
Примерно так. Только он вообще не использует в этом случае копирование. Почитай про move–конструкторы. Очень полезная штука.
|
Сообщ.
#10
,
|
|
|
раньше читал, но надо освежить знания, про все эти фишки С++11/14: перемещающие операции, идеальную передачу параметров, переменные шаблоны и тд
|
Сообщ.
#11
,
|
|
|
В первую очередь обрати внимание на эти конструкторы и на универасальные ссылки, std::forward
|
Сообщ.
#12
,
|
|
|
ok
кстати обнаружил что emplace_back реализуется через push_back, думаю в моем случае push_back(std::move(ob)) имеет тот же эффект? |
Сообщ.
#13
,
|
|
|
Не стоит. А какой ты компилятор используешь?
Добавлено Кстати, в случае с вектором такая реализация emplace-back вполне возможна. В случае же списком – не вижу смысла. Добавлено Хотя, и там тоже не вижу |
Сообщ.
#14
,
|
|
|
Цитата Олег М @ Не стоит. А какой ты компилятор используешь? Visual Studio 2010 |
Сообщ.
#15
,
|
|
|
Цитата Cfon @ кстати обнаружил что emplace_back реализуется через push_back, думаю в моем случае push_back(std::move(ob)) имеет тот же эффект? Точно, в 11 стандарте появилась декларация void push_back (value_type&& val); Не обращал внимания, всегда пользовался emplace_back. Значит да, в твоём случае наверное без разницы. |