Здравствуйте, 13akaEagle, Вы писали:
E>Здравствуйте, Ubivetz, Вы писали:
U>>Реализацию friend bool operator>(const Game& left, const Game& rigth); в студию. U>>Скорее всего там бочина.
E>
Здравствуйте, 13akaEagle, Вы писали:
E>Здравствуйте, Ubivetz, Вы писали:
U>>Не пойму ещё, как оно может выводить U>>
U>>Estonia Litva
U>>Estonia Litva
U>>Estonia Estonia
U>>??? U>>Может ты что-то путаешь?
E>Да вроде ничего не путаю. E>Понять ничего не могу, но мне кажется, что make_heap что-то делает неправильно.
Когда ты ему указываешь std:greater<Game>(), ты этим самым сортируешь коллекцию.
Почему у тебя появилась пара Estonia Estonia?
Эх, люблю выпить и переспать с кем нибудь!
Но чаще выходит перепить с кем — нибудь и выспаться...
Здравствуйте, Ubivetz, Вы писали:
U>Когда ты ему указываешь std:greater<Game>(), ты этим самым сортируешь коллекцию. U>Почему у тебя появилась пара Estonia Estonia?
Вот ради этого я и решил попросить совета в форуме.
Здравствуйте, a-lex, Вы писали:
AL>Здравствуйте, 13akaEagle, Вы писали:
AL>
AL> g.push_back(Game(a, b, "25.12.2006"));
AL> g.push_back(Game(c, b, "26.12.2006")); // теперь a == c
AL> g.push_back(Game(a, c, "27.12.2006")); // теперь b == c
//в отдалчике контейнер g имеет нужные значения
//здесь всё ещё всё в порядке
AL> make_heap(g.begin(), g.end(), std::greater<Game>()); //<----- а вот здесь всё портиться
AL> for (std::vector<Game>::iterator it = g.begin(); it != g.end(); ++it)
AL> {
AL> Game& game = static_cast<Game>(*it);
AL> std::cout << game._first._name << " " << game._second._name << std::endl;
AL> }
AL>}
AL>
Здравствуйте, 13akaEagle, Вы писали:
E>Здравствуйте, a-lex, Вы писали:
AL>>Здравствуйте, 13akaEagle, Вы писали:
AL>>
AL>> g.push_back(Game(a, b, "25.12.2006"));
AL>> g.push_back(Game(c, b, "26.12.2006")); // теперь a == c
AL>> g.push_back(Game(a, c, "27.12.2006")); // теперь b == c
E>//в отдалчике контейнер g имеет нужные значения
// тьфу, точно. тут же просто добавляются новые значения...
E>//здесь всё ещё всё в порядке
AL>> make_heap(g.begin(), g.end(), std::greater<Game>()); //<----- а вот здесь всё портиться
// а вот здесь они начинают копироваться внутри make_heap,
// и происходит то, что я написал в комментариях на пуш_бэки
AL>> for (std::vector<Game>::iterator it = g.begin(); it != g.end(); ++it)
AL>> {
AL>> Game& game = static_cast<Game>(*it);
AL>> std::cout << game._first._name << " " << game._second._name << std::endl;
AL>> }
AL>>}
AL>>
Здравствуйте, a-lex, Вы писали:
AL>Здравствуйте, 13akaEagle, Вы писали:
E>>Здравствуйте, a-lex, Вы писали:
AL>>>Здравствуйте, 13akaEagle, Вы писали:
AL>>>
AL>>> make_heap(g.begin(), g.end(), std::greater<Game>()); //<----- а вот здесь всё портиться
AL>// а вот здесь они начинают копироваться внутри make_heap,
AL>// и происходит то, что я написал в комментариях на пуш_бэки
AL>>>
Team tmp = a; //save russia
a = b; //russia -> litva
b = tmp; //litva -> russia
А вот здесь всё в порядке. Каким образом они копируются при создании пирамиды?
PS: Сразу оговорюсь, я не знаю что за пирамида(бинарное дерево) ( ) и как там всё реализуется. Просто у меня std::priority_queue<Game> и он работает не очень корректно.
Здравствуйте, a-lex, Вы писали:
AL>Еще раз. Проблема в Game::operator=. Team в данном случае не виновата.
Действительно. А как тогда будет выглядеть правильный Game::operator= ?
Здравствуйте, 13akaEagle, Вы писали:
AL>>Еще раз. Проблема в Game::operator=. Team в данном случае не виновата. E>Действительно. А как тогда будет выглядеть правильный Game::operator= ?
Интересный вопрос Единственный способ скопировать ссылку, это присвоить её в конструкторе.
Этот фрагмент кода используется как пример неверного, потому что если конструктор кинет исключение, объект останется разрушенным. Но в твоем случае объект простой, ничего не кидает, можно использовать. А самый правильный способ, это, очевидно, заменить ссылки на указатели.
Здравствуйте, 13akaEagle, Вы писали:
AL>>Еще раз. Проблема в Game::operator=. Team в данном случае не виновата. E>Действительно. А как тогда будет выглядеть правильный Game::operator= ?
Ну, это уже зависит от того, какое поведение класса Game Вы хотите получить.
Вариант 1.
Убираем ссылки (правда ли они нужны? разве мы собираемся менять значения команд через обекты "игра"?) и получаем класс с семантикой "значение" тривиальным способом.
struct Game
{
Team _first; // ссылка убрана
Team _second; // ссылка убрана
Score score;
// TDateTime _datetime;
std::string _datetime;
Game(const Team& first, const Team& second, const std::string& datetime);
//убираем -- сойдет и созданный компилятором Game& operator=(const Game& game);
friend bool operator>(const Game& left, const Game& rigth);
};
Побочный эффект: теперь каждый объект Game хранит копии объектов Team, а не ссылается на переданные ему в конструкторе команды.
Вариант 2.
Если хотим, чтобы объекты Game не хранили копии Team'ов, а ссылались на уже существующие команды.
struct Game
{
Team* _first; // указатель вместо ссылки
Team* _second; // указатель вместо ссылки
Score score;
// TDateTime _datetime;
std::string _datetime;
Game(Team& first, Team& second, std::string datetime);
//убираем -- сойдет и созданный компилятором Game& operator=(const Game& game);
friend bool operator>(const Game& left, const Game& rigth);
};
Обратите внимание, что при копировании/присваивании объектов Game копируются указатели на объекты Team. Для облегчения управления их временем жизни вместо голых указателей лучше использовать умные (например, boost::shared_ptr<Team>).
Тут объекты Game получаются некопируемыми. Тогда в контейнере надо хранить (умные) указатели на Game (например, boost::shared_ptr). Алгоритмам типа make_heap придется передавать свой функтор для сравнения указуемых объектов.
Кё>Этот фрагмент кода используется как пример неверного, потому что если конструктор кинет исключение, объект останется разрушенным. Но в твоем случае объект простой, ничего не кидает, можно использовать. А самый правильный способ, это, очевидно, заменить ссылки на указатели.
Угу, давно всё сделал на share_ptr.
Просто хотел узнать в чём дело с ссылками...
AL>Если хотим, чтобы объекты Game не хранили копии Team'ов, а ссылались на уже существующие команды. AL>
AL>struct Game
AL>{
AL> Team* _first; // указатель вместо ссылки
AL> Team* _second; // указатель вместо ссылки
AL> Score score;
AL>// TDateTime _datetime;
AL> std::string _datetime;
AL> Game(Team& first, Team& second, std::string datetime);
AL>//убираем -- сойдет и созданный компилятором Game& operator=(const Game& game);
AL> friend bool operator>(const Game& left, const Game& rigth);
AL>};
AL>
С share_ptr и сделал.
AL>Обратите внимание, что при копировании/присваивании объектов Game копируются указатели на объекты Team. Для облегчения управления их временем жизни вместо голых указателей лучше использовать умные (например, boost::shared_ptr<Team>).
AL>
AL> friend bool operator>(const Game& left, const Game& rigth);
AL>};
AL>
AL>Тут объекты Game получаются некопируемыми. Тогда в контейнере надо хранить (умные) указатели на Game (например, boost::shared_ptr). Алгоритмам типа make_heap придется передавать свой функтор для сравнения указуемых объектов.
Об это варианте я даже не знал.