代码之家  ›  专栏  ›  技术社区  ›  Stephano

为什么pop()要接受一个参数?

  •  9
  • Stephano  · 技术社区  · 16 年前


    我是一个java开发者,在我空闲的时候,一直在玩C++。

    前言
    在C++中,你经常会看到POP引用引用的参数:

    void pop(Item& removed);
    

    我知道用删除的内容“填充”参数很好。这对我来说完全有道理。这样,要求删除顶部项目的人可以查看删除的内容。

    但是,如果我用Java做这个,我会这样做:

    Item pop() throws StackException;
    

    这样,在pop之后,我们将返回以下任一结果:NULL、条目或异常将被抛出。

    stl stack 例如)。

    问题

    奖金
    为什么?

    5 回复  |  直到 16 年前
        1
  •  26
  •   Dan    13 年前

    要回答这个问题:您不应该在C++中实现POP函数,因为它已经由STL实现了。这个 std::stack 容器适配器提供了 top 获取对堆栈顶部元素的引用,以及 pop 移除顶部元件。请注意 流行音乐 方法不能单独用于执行这两个操作,正如您所问的。

    1. 例外安全: 赫伯·萨特在书中很好地解释了这个问题 GotW #82
    2. 单一责任原则: 在GotW#82中也提到了。 承担一项责任 流行音乐
    3. 不要为你不需要的东西付钱: 对于某些代码,只需检查顶层元素,然后将其弹出即可,而无需制作元素的副本(可能很昂贵)(报告中提到了这一点 SGI STL 文档。)

    任何希望获得元素副本的代码都可以这样做,而不需要额外的费用:

    Foo f(s.top());
    s.pop();
    

    this discussion 可能很有趣。

    RVO

        2
  •  4
  •   wilhelmtell    16 年前

    Java方法的问题在于 pop() 方法至少有两种效果:删除元素和返回元素。这违反了软件设计的单一责任原则,从而为设计复杂性和其他问题打开了大门。这也意味着性能损失。

    以STL的方式,我们的想法是

    如果您提供了两个重载,一个引用另一个不引用,那么您允许用户选择他(或她)是否对返回的元素感兴趣。呼叫的性能将达到最佳。

    弹出() back() (或 top() 在这种情况下 std::stack 弹出() 后退() 函数只返回元素,而 函数只是删除它。

        3
  •  1
  •   ablaeul    16 年前

    用C++ 0x使整个事情变得困难起来。

    作为

    stack.pop(item); // move top data to item without copying
    

    可以有效地从堆栈中移动顶部元素。鉴于

    item = stack.top(); // make a copy of the top element
    stack.pop(); // delete top element
    

        4
  •  0
  •   Stack Overflow is garbage    16 年前

    在C++中我可以看到使用这种语法的唯一原因:

    void pop(Item& removed);
    

    如果你担心不必要的拷贝发生。

    如果你归还 Item ,它 需要对象的附加副本 价格昂贵。

    更快 在某些情况下。

    担心 将

    更多信息 here

        5
  •  0
  •   Nemanja Trifunovic    16 年前

    IMO,一个很好的签名 pop C++中的函数将是:

    boost::optional<Item> pop();
    

    使用选项类型是返回可能可用或不可用内容的最佳方法。