Как реализовать стек с помощью std :: vector?

0

Я пытаюсь понять, как нажать, поп и получить вершину std :: vector, которая в основном представляет собой реализацию стека в c++ с векторами.

Моя реализация полностью работает, но я не совсем уверен, что она обрабатывает ресурсы, как следует, если все в порядке, отлично. Я не нашел много примеров этого, так что это поможет другим, если это не так, пожалуйста, предоставьте информацию о том, как его улучшить, ошибки, которые могут возникнуть, и т.д.

Это мой текущий код:

std::vector<std::unique_ptr<Estado>> vecEstados;
// PUSH
void push(Estado *es){
vecEstados.emplace_back(es); // (MENU IS A SUBCLASS OF ESTADO)
}
// GET TOP
Estado *get_top()
{
    return vecEstados.back().get();
}
// POP (THIS SHOULD JUST ERASE LAST ITEM)
void pop()
{
    vecEstados.erase(vecEstados.end()-1);
}
Теги:
vector
stack

2 ответа

3
Лучший ответ

PUSH: используйте push_back вместо emplace_back, если вы передадите элемент с правильным типом. emplace_back делает явные конструкторы неявными. Поэтому используйте его, только если есть причина. Вы должны использовать std::move с std::unique_ptr, потому что std::unique_ptr unique_ptr не копируется.

vecEstados.push_back(std::move(es));

Если вы создаете новый элемент, вы можете использовать std::make_unique если он доступен (С++ 14). Однако в этом случае это не имеет большого значения:

vecEstados.emplace_back(std::make_unique<Menu>());
vecEstados.push_back(std::unique_ptr<Estado>(new Menu{}));

TOP: Если вы не собираетесь изменять возвращаемый объект, тогда создайте функцию const. Для согласованности я бы вернул std::unique_ptr<Estado> вместо Estado*.

const std::unique_ptr<Estado>& get_top() const
{
    return vecEstados.back();
}

POP: вы должны использовать pop_back для удаления последнего элемента std::vector. Вы также можете объявить эту функцию с помощью noexcept, поскольку она упрощает запись правильного кода очистки.

void pop() noexcept
{
    vecEstados.pop_back();
}
  • 0
    Я попытался заменить emplace_back на push_back, однако у меня не получилось ошибочной no matching function for call to 'std::vector<std::unique_ptr<Estado> >::push_back(std::remove_reference<Estado*&>::type)'|
  • 0
    Я реализовал как топовые, так и поп-решения без проблем, дайте мне знать, если вы знаете, что не так с push
0

Как упоминалось в P0W, std :: stack уже существует. Я также согласился бы с нозовыми ответами.

Я предполагаю, что упражнение несколько избыточно, но для имитации интерфейса, который std :: stack предоставляет (или его часть), я бы предложил что-то вроде:

template<class Type>
class LisoStack
{
public:
    LisoStack() : mStack() {}

    // Push onto the top of the stack
    Type push(const Type& val)
    { 
        mStack.push_back(std::move(val));
    } 

    // Get the element at the top
    Type& top()
    { 
        return mStack.back();
    } 

    // Get the element at the top
    const Type& top() const
    { 
        return mStack.back();
    } 

    // Remove the element at the top
    void pop() noexcept
    {
        mStack.pop_back();
    }

private:
    std::vector<Type> mStack;
};
  1. Шаблон, чтобы сделать контейнер общим.
  2. Замените get_top() на top() и просто сделайте.back(), чтобы предоставить элемент в конце вектора (верхняя часть стека). Укажите версии const и non-const.
  3. Функция pop() просто вызывает vector.pop_back(), которая делает то, что вы хотите - удаляет последний элемент (верхнюю часть стека).
  4. Как упоминалось выше, предпочитайте push_back() в вашем случае (обратите внимание, что это также поддерживает совместимость с компиляторами pre С++ 11). У вас есть возможность реализовать отдельную функцию emplace(), которую предоставляет std :: stack.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню