Ничто не вопиюще неправильно в то, что вставил там, так что, вероятно, будет ошибка в долгосрочном вызове, который создает набор.
Например, было бы легко испортить это, если при добавлении элементов в набор будут задействованы необработанные указатели. Рассмотрим эту ситуацию, конкретная иллюстрация общей ошибкой, которая вроде была упомянута в вашей лучшей практике ссылка:
std::set<World::CPtr> first_world;
World* pWorld = new World();
// Bad:
first_world.insert(World::CPtr(pWorld));
first_world.insert(World::CPtr(pWorld));
// Oops!! You now have two independently refcounted entries in first_world!
// emplace is just as deadly, but more subtle.
// Now you'll have three shared pointers in your set:
first_world.emplace(pWorld);
Если вы смотрите через ваши записи в first_world
и увидеть дубликаты, то вы будете знать, что вы в беде , Чтобы избежать таких ошибок, убедитесь, что вы только создаете shared_ptrs из других shared_ptrs (или boost::make_shared
).
Так вот кончик # 1: Избегайте конструирования shared_ptrs
от необработанных указателей. (Это включает в себя указатель this
, если миры добавляют себя к вашему набору ... если вы это делаете, лучше начинайте поиски по Google enable_shared_from_this
).
Теперь давайте проследим, что руководство, чтобы получить ожидаемое поведение:
std::set<World::CPtr> first_world;
World::CPtr spWorld1 = boost::make_shared<World>();
World::CPtr spWorld2{spWorld1};
first_world.insert(spWorld1);
first_world.insert(spWorld2);
// Just one element in first_world now, as expected.
Наконец, несколько (несколько не связанных между собой) предложения:
std::set
, как вы объявили его смотрит только на адрес объектов World в куче, когда он сравнивает записи. Поэтому, если у вас есть два разных мира в куче, которые логически идентичны, то они оба будут иметь разные записи в наборе. Это ваше намерение? Вам нужно будет подключить собственную функцию сравнения (второй аргумент шаблона std :: set), чтобы выполнить глубокое сравнение миров, если вы хотите избежать логических дубликатов.
- Убедитесь, что
first_world
не пуст перед поиском максимального значения, в противном случае произойдут плохие вещи.
- Стандартные алгоритмы - ваш друг! Рассмотрите возможность использования алгоритма
std::max_element
вместо необработанного цикла. (Это облегчает для других людей рассуждать о том, что вы делаете, с быстрым взглядом).
Почему вы используете 'boost :: shared_ptr', когда вы, очевидно, используете C++ 11? – molbdnilo
@molbdnilo Почему бы и нет? Кажется, не имеет значения. В прошлый раз, когда я проверял типы, не то же самое, и имеет смысл использовать тот тип, который требуется вашей кодовой базе ... – sehe
ну C++ 11 не нужно, я бы изменил его на более старый стандарт - что я хочу понять почему это не работает, как заставить его работать. – beginh