удалить резервное слово, не вызывающее деструктор при первом проходе цикла - PullRequest
1 голос
/ 03 декабря 2011

Я создал простую программу, которая «рисует» фигуры в командной строке.Я использую несколько реализаций классов, но основная проблема заключается в абстрактном классе Command, точнее в деструкторе этого класса.Я компилирую его в определенном мной режиме DEBUG, который печатает '-' каждый раз, когда деструктор удаляет объект.

Класс Command выглядит примерно так:

class Command {
    public:
        Command(){
#ifdef DEBUG
            std::cout << '+';
#endif
        }
        virtual ~Command() {
#ifdef DEBUG
            std::cout << '-';
#endif
        }   
        virtual void execute() = 0;
        virtual void unexecute() = 0;
};

Цикл, который я вызываю в другом классе, выглядит следующим образом:

vector<Command*>  history_;

while(position_ != 0) {
    delete *history_.end();
    history_.pop_back();
    position_--;
}

, если position_ большечем 1, он печатает '-' n - 1 раз, но не вызывает деструктор при первом удалении цикла.

Ответы [ 4 ]

3 голосов
/ 03 декабря 2011

Ну, последний элемент вектора не *history_.end(), это history_.back().

Теперь, если position действительно указывает позицию, вы должны позволить ей достичь 0. Если это, однако, подсчет количества предметов, вы должны вместо этого переименовать ее в count или size.

Поскольку вектор уже включает средства для проверки, когда он пуст, вы даже можете отказаться от своего пользовательского счетчика и не беспокоиться о том, должен ли он достигать 0 или нет:

while(!history.empty()) {
    delete history_.back();
    history_.pop_back();
}

Но так как вы на самом деле очищаете весь вектор, нет необходимости вставлять по одному элементу за раз. Вы можете перебирать вектор, удалять их, а затем clear() вектор сразу.

for(size_t i = 0; i < history_.size(); ++i) {
    delete history[i];
}
history_.clear();

Или в C ++ 11:

for(auto ptr : history_) {
    delete ptr;
}
history_.clear();
1 голос
/ 03 декабря 2011

Для контейнера STL end() ссылается не на последний элемент , а на место сразу после последнего элемента.

0 голосов
/ 03 декабря 2011

У вас есть пара проблем:

  • end() относится к один за концом вектора, для вас недопустимым элементом является delete (вы приняли end() за back()). Поскольку вы используете переменную count для итерации цикла, вы также можете использовать произвольный доступ (т. Е. history_end[i]) для доступа к элементам в vector.

  • Ваше состояние должно быть position_ >= 0, чтобы 0-й элемент мог быть delete d.

0 голосов
/ 03 декабря 2011

Это потому, что 0 не будет удалено, потому что position_ != 0 исключает 0, поэтому у вас останется одна команда в векторе.
Измените его на

while(position_ >= 0)

, а затем 0 также будет удалено.

...