为什么 pop() 应该接受一个论点?
快速背景
我是一名 Java 开发人员,在空闲/无聊的时候一直在玩 C++.
Quick background
I'm a Java developer who's been playing around with C++ in my free/bored time.
前言
在 C++ 中,您经常会看到 pop 通过引用获取参数:
Preface
In C++, you often see pop taking an argument by reference:
void pop(Item& removed);
我知道用您删除的内容填充"参数很好.这对我来说完全有道理.这样,要求删除顶部项目的人可以查看已删除的内容.
I understand that it is nice to "fill in" the parameter with what you removed. That totally makes sense to me. This way, the person who asked to remove the top item can have a look at what was removed.
但是,如果我要在 Java 中执行此操作,我会执行以下操作:
However, if I were to do this in Java, I'd do something like this:
Item pop() throws StackException;
这样,在弹出之后我们返回:NULL 结果,一个项目,或者一个异常将被抛出.
This way, after the pop we return either: NULL as a result, an Item, or an exception would be thrown.
我的 C++ 教科书向我展示了上面的示例,但我看到很多堆栈实现不带参数 (stl stack 例如).
My C++ text book shows me the example above, but I see plenty of stack implementations taking no arguments (stl stack for example).
问题
C++如何实现pop函数?
The Question
How should one implement the pop function in C++?
奖金
为什么?
推荐答案
回答问题:你不应该在C++中实现pop函数,因为它已经被STL实现了.std::stack
容器适配器提供top
方法获取栈顶元素的引用,pop
方法移除顶元素.请注意,pop
方法不能单独用于执行这两个操作,正如您所询问的那样.
To answer the question: you should not implement the pop function in C++, since it is already implemented by the STL. The std::stack
container adapter provides the method top
to get a reference to the top element on the stack, and the method pop
to remove the top element. Note that the pop
method alone cannot be used to perform both actions, as you asked about.
为什么要这样做?
- 异常安全性: Herb Sutter 在 GotW #82.
- 单一职责原则: 在 GotW #82 中也提到过.
top
负责一项职责,而pop
负责另一项职责. - 不要为不需要的东西买单:对于某些代码,检查顶部元素然后弹出它可能就足够了,而无需制作(可能很昂贵)的副本元素.(这在 SGI STL 文档中有所提及.)
- Exception safety: Herb Sutter gives a good explanation of the issue in GotW #82.
- Single-responsibility principle: also mentioned in GotW #82.
top
takes care of one responsibility andpop
takes care of the other. - Don't pay for what you don't need: For some code, it may suffice to examine the top element and then pop it, without ever making a (potentially expensive) copy of the element. (This is mentioned in the SGI STL documentation.)
任何希望获得元素副本的代码都可以免费执行此操作:
Any code that wishes to obtain a copy of the element can do this at no additional expense:
Foo f(s.top());
s.pop();
另外,这个讨论可能很有趣.
如果您要实现 pop 来返回值,那么是按值返回还是将其写入 out 参数并不重要.大多数编译器都实现了 RVO,这将优化按值返回的方法以同样高效作为copy-into-out-parameter方法.请记住,其中任何一个都可能比使用 top() 或 front() 检查对象的效率低,因为在这种情况下,绝对不会进行复制.
If you were going to implement pop to return the value, it doesn't matter much whether you return by value or write it into an out parameter. Most compilers implement RVO, which will optimize the return-by-value method to be just as efficient as the copy-into-out-parameter method. Just keep in mind that either of these will likely be less efficient than examining the object using top() or front(), since in that case there is absolutely no copying done.
相关文章