如何使用std :: vector实现堆栈?

时间:2013-10-12 19:34:20

标签: c++ vector stack

我正在尝试理解如何推送,弹出并获取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);
}

2 个答案:

答案 0 :(得分:3)

推送:如果您传递的元素类型正确,请使用push_back代替emplace_backemplace_back使显式构造函数隐式。所以只有在有原因时才使用它。您必须将std::movestd::unique_ptr一起使用,因为std::unique_ptr不可复制。

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

如果您创建了一个新元素,则可以使用std::make_unique(如果可用)(C ++ 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();
}

答案 1 :(得分:0)

如P0W所述,std :: stack已经存在。我也同意nosid的答案。

我想这个练习有些多余,但为了模仿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. 用top()替换get_top(),然后执行.back()以提供向量背面的元素(堆栈的顶部)。提供const和非const版本。
  3. pop()只是调用vector.pop_back()来做你想要的 - 删除最后一个元素(栈顶)。
  4. 正如nosid所提到的,在你的情况下更喜欢push_back()(请注意,这也保持与前C ++ 11编译器的兼容性)。你可以选择实现一个单独的emplace()函数,如std :: stack提供的那样。