Это правильно?:
std::vector<Enemy*> enemies;
enemies.push_back(new Enemy());
Enemy* enemy = enemies[0];
enemies.erase(enemies.begin() + 0);
delete enemy;
Это правильно?:
std::vector<Enemy*> enemies;
enemies.push_back(new Enemy());
Enemy* enemy = enemies[0];
enemies.erase(enemies.begin() + 0);
delete enemy;
Да, это работает, но это не идеальный подход.
Во-первых, добавление 0 - это просто шум, его можно убрать. Но даже лучше, просто используйте pop_front()
. Кроме того, нет необходимости в промежуточном шаге, вы можете удалить его перед удалением.
Но std::vector
не подходит для того, чтобы появляться спереди, особенно если он большой (потому что оставшиеся элементы нужно сдвинуть, чтобы заполнить пустоту). Если вам не нужна непрерывная память, используйте вместо нее std::deque
. Или, если порядок не имеет значения, вы можете использовать что-то вроде этого:
template <typename T, typename A>
void unordered_pop_front(std::vector<T, A>& vec)
{
using std::swap;
swap(vec.front(), vec.back()); // constant time
vec.pop_back(); // constant time
}
Он меняет местами передний элемент на задний элемент, а затем снимает его. Конечно, порядок не соблюдается.
Другая проблема связана с вашим подходом к управлению памятью. Каждый раз, когда у вас есть явный код очистки, вы сделали что-то не так. Это должно выполняться автоматически.
Используйте либо Boost ptr_vector
, либо std::vector
умных указателей. (Примечание: не используйте std::auto_ptr
в контейнере, в этом отношении он не работает.) Для быстрого предложения умного указателя используйте либо std::unique_ptr
(если ваш компилятор поддерживает C ++ 0x), либо std::/boost::shared_ptr
.
std::vector<Enemy*> enemies;
enemies.push_back(new Enemy());
Это не безопасно. Если push_back
не удается выделить достаточно памяти для размещения нового указателя, происходит утечка объекта Enemy
.
Использование вектора интеллектуальных указателей может решить эту проблему, но в противном случае вы должны зарезервировать пространство в векторе, прежде чем возвращаться:
std::vector<Enemy*> enemies;
enemies.reserve(1); // or more generally, enemies.reserve(enemies.size()+1);
enemies.push_back(new Enemy());
Теперь мы знаем, что push_back
не может не выделить память, и если reserve
не удается, то исключение выдается до создания Enemy
.
Конечно, мне нравится. Вам не нужен + 0
в строке enemies.erase
, но в остальном это нормально.
Да, это нормально. Можно немного упростить:
delete enemies[0];
enemies.clear();
Для удаления элемента вы также можете использовать:
enemies.pop_back();
или (очень похоже на ваш):
enemies.erase(enemies.begin());
delete
вызывает деструктор указанного объекта, затем освобождает память.
- person GManNickG; 27.03.2011
boost::ptr_vector
. - person Björn Pollex   schedule 27.03.2011push_back(new Enemy)
? Разве вы не знали, что толкать врага в спину несправедливо? :-D - person P Shved   schedule 27.03.2011