2012-03-14 2 views
-3

У меня возникла проблема в моей игре на C++, связанной с вектором. Я хочу знать, есть ли какой-либо код, который говорит мне, существует ли вектор. Пример (х = структуру, которую я создал):Сохраняется ли вектор?

vector<x*> var; 
var.push_back(new x); 
var[5]->Pos_X = 10; 

А теперь, что я хочу:

delete var[5]; 

if(var[5] still exists){ 
    var[5]->Pos_X = 20; 
} 

Что может быть код вар [5] все еще существует?

+13

Здесь я чувствую плохой дизайн. Также: определение «все еще существует». – Griwes

+1

Зачем вам хранить указатели? – Overv

+0

Поскольку структура используется для объектов в игре. –

ответ

4

Если вы не на самом деле установить указатель на нуль после его удаления, нет никакого реального способа, чтобы определить, содержит ли этот слот в векторе указатель на живого объекта или нет.

Таким образом, вы должны были бы: delete vec[5]; vec[5] = NULL;

Тогда вы могли бы проверить

if (vec[5] == NULL)

, чтобы определить, есть ли «действительно» что-то в этом месте или нет.

+0

Давайте попробуем! Спасибо –

+0

Надеюсь, я правильно истолковал ваш вопрос. Я думаю так. –

+0

Да, это именно то, чего я ожидал. Спасибо! –

3

Для этого нет никакого кода, не без дополнительной тщательной работы в процессе удаления. Если вы храните смарт-указатели вы можете сделать это следующим образом:

vector<unique_ptr<x>> var; 
// assuming you actually do add 6 or more elements to the vector 
... 
var[5].reset(); 

if (var[5]) { ... } 
+2

Если вы настаиваете на сохранении указателей, умные указатели - это путь. – chris

+0

Я понимаю, я посмотрю, что я собираюсь делать ... –

0

вызов delete вы освобождаете память, указанную этим x *, поэтому у вас все еще есть указатель на некоторый адрес памяти, который больше не содержит то, что вы пробовали.

Если вы хотите удалить элементы из вектора, попробуйте использовать «erase»; то, если вы не хотите стирать, а просто «отмените» элемент Nth, структура ваша. Поместите в свою структуру некоторый флаг bool.

+0

Хорошо, не могли бы вы привести мне пример? –

+0

Если вы хотите, чтобы ваше векторное пространство было выделено (чтобы не стирать элементы), добавьте в свою структуру bool valid; поле, тогда, когда вы хотите удалить его (фактически «invalidate»): var [5] .valid = false; и когда вы хотите снова проверить, установите значение true. Если вам не нужна свободная память, это легкое решение; то вы можете инкапсулировать эту логику внутри некоторого метода или обертки так же, как @Jerry Coffin сказал – kappa

1

Вы можете использовать var.size(), чтобы увидеть, содержит ли вектор указатель в var[5], но это не скажет вам, является ли указатель действительным.

Вы могли бы создать небольшой класс-обертку:

template <class T> 
class wrapper { 
    bool valid; 
    T *data_; 
public: 
    wrapper(T *d): data_(d), valid(true) {} 
    del() { delete data; valid = false; } 
    bool isValid() { return valid; } 
    T *data() { return valid ? data : NULL; } 
}; 

std::vector<wrapper<x> > var; 

var[5].del(); 

if (var[5].valid()) 
    var[5].data()->Pos_X = 20; 

Лично я предпочел бы, чтобы просто убедиться, что все указатели действительны все время, хотя.

+0

Надеюсь, что это сработает! –

+0

@TiagoSalzmann: Для достаточно узкого определения «работ». Если, например, вы копируете один из них и используете 'del()' в одной копии, другой не будет знать, что данные были удалены. Я также немного отредактировал код, чтобы исправить пару незначительных ошибок (но он все еще не проверен, а тем более доказан, поэтому вероятнее всего будет несколько ошибок. –

Смежные вопросы