社区
工具平台和程序库
帖子详情
关于STL的stack的疑问
qiaojicheng
2003-12-29 09:01:24
我使用的是VC自带的STL,它里面堆栈的实现代码中pop这样定义:
void pop();
而另外定义了一个 value_type& top();
为什么不像常规那样pop返回一个值呢?这样定义很不习惯,要先取值,再弹出,很容易忘记弹出操作呀!
...全文
266
12
打赏
收藏
关于STL的stack的疑问
我使用的是VC自带的STL,它里面堆栈的实现代码中pop这样定义: void pop(); 而另外定义了一个value_type& top(); 为什么不像常规那样pop返回一个值呢?这样定义很不习惯,要先取值,再弹出,很容易忘记弹出操作呀!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
12 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
hz129
2003-12-30
打赏
举报
回复
我在linux g++3.2.2下运行,底层容器不同结果也不同,以deque和vector为底层容器时,栈空时top调用导致段错误。以list为底层容器时top调用返回0。
栈top()会调用底层容器的back()操作,deque和vector为空时,back()操作会使用空指针,而list为双向循环链,有一个作为链头的标志块,所以调用back()是不会导致空指针操作。但执行pop()操作时会出错。
#include <stack>
#include <list>
#include <iostream>
using namespace std;
int main() {
stack< int, list<int> > s;
cout << "s.top()=" << s.top() << endl;
s.pop();
}
STL对空栈调用top和pop应该是未定义的,可能设计者认为使用STL的人应该知道自己在做什么,如果想要比较安全的使用,可能JAVA的异常机制会更理想一些。
qiaojicheng
2003-12-30
打赏
举报
回复
古雨:
对于top,是必须的,有些实现使用peek(一瞥),很形象,和pop加以区分;
对于pop,谢谢你的解释,我没有考虑到构造和拷贝的开销。
还有一个问题,栈空时top的调用会导致什么结果?
hz129
2003-12-30
打赏
举报
回复
我觉得可以从效率方面考虑:
首先value_type& top();这个函数是不可少的。
对于pop,需要将栈顶元素弹出,定义为value_type& pop()显然是不合适的。因为如果返回的是个引用,则栈顶元素不能被析构,此时又不能保证返回值会被应用,那么这个元素的析构时机就没法确定了,极有可能造成内存泄漏,如果改为value_type pop(),则在返回值不被使用的时候,平白无故的多用了一次拷贝构造函数,这与STL对效率的追求是相悖的。而分为两个函数,可以让使用者决定是否需要这个拷贝构造,最大化了效率。
eg:
X& a = XStack.top();
...
XStack.pop(); // 此时a将失效
X a = XStack.top();
...
XStack.pop(); // a仍然有效,执行赋值时会调用拷贝构造函数
qiaojicheng
2003-12-30
打赏
举报
回复
xiaocai365(小菜)
我是说我设计的话就让它抛出一个异常,STL确实没有这样做。
之所以抛出异常是因为当使用者不合理的使用时给他一个提示,本来就应该先检查栈是否为空的。
STL在栈空时什么反应都没有,岂不是更不容易调试的时候发现问题,使用者也就很容易忘记检查了。
Robin
2003-12-29
打赏
举报
回复
按照你的思路的话,假如Clients继承了她之后,也许会出现这中情况!
Robin
2003-12-29
打赏
举报
回复
stephenland74(程序员)说的也有道理!
如果出现了Exception,在函数内部抛出Exception,也许会给大家造成更大的疑惑!
这样做的话,让我们自己来检测Exception!
Robin
2003-12-29
打赏
举报
回复
为了最大程度的满足用户的需要!
这两个Interface的意义是什么呢!
xiaocai365
2003-12-29
打赏
举报
回复
qiaojicheng(乔)
标准库中的stack在pop下溢时无定义,而不是抛出异常。
抛出异常的代价就会高一些。
话说回来pop下溢的确是可以防护的,不过以上这些思考,恰好说明了标准库中的设计比较简单。
stephenland74
2003-12-29
打赏
举报
回复
因为要保证操作的原子性,如果top和pop一样,当pop操作发生异常的时候,top并没有使栈顶的指针减一,而此时函数就退出了,如果下一次的调用继续的话,该栈的指针就会永远错下去,也许这个问题并不是很难解决,但只是这样的解决方法,会引发一些不合理的代码,而求在类的设计上也是一个隐患。
qiaojicheng
2003-12-29
打赏
举报
回复
xiaocai365(小菜)
pop之前应该查询是否为空,这样设计我也要查询呀,如果为空,就抛出一个异常,很正常呀!
Polarislee(北极星)
pop的语意就是弹出,返回栈顶值,搞成这样觉得很不习惯。
北极猩猩
2003-12-29
打赏
举报
回复
将查询与操作分离,最简单的思想。习惯就好了:P
xiaocai365
2003-12-29
打赏
举报
回复
对设计会有简化作用。
试想如果对空的栈 pop(),应该弹不出东西,
如果让你来设计 value_type& pop(),会怎样做。
C++
STL
STL
实战开发精讲视频
《C++ 模板技术与
STL
实战开发》主讲:丁宋涛 泛型编程(Generic Programming)是一种全新的程序设计思想,它和
STL
是现代C++的精髓。可以说,不会
STL
很难称得上掌握了现代C++编程。
STL
...
Deque 的理解
STL
中
stack
与queue为什么选择使用deque为底层模板容器
Deque的理解,为什么
STL
选择使用Deque来作为
stack
与queue的底层模板容器。
通过C++
stl
文档简单了解
stack
运算符的重载
在实现的过程中,个人对于
stack
的了解又深入了一步,尤其是关于
stack
的运算符的重载方面。于是决定写自己的第一篇博客,就当时自己的学习记录,同时也分享一下自己百度搜索无果的
stack
的比较运算符的重载机制
关于
STL
前言:在某文库上下载的文档,觉得讲的不错,做此分享。作为C++标准不可缺少的一部分,
STL
应该是渗透在C++程序的角角落落里的。... 1 初识
STL
:解答一些
疑问
1.1 一个最关心的问题:什么是
STL
“什么是
STL
?”,假
STL
总结二
stack
容器 简介
stack
是堆栈容器,是一种“先进后出”的容器。
stack
是简单地装饰deque容器而成为另外的一种容器。 栈不能遍历,不支持随机随机存取,只能通过top从栈顶获取和删除元素
stack
的push()与pop()...
工具平台和程序库
24,854
社区成员
27,343
社区内容
发帖
与我相关
我的任务
工具平台和程序库
C/C++ 工具平台和程序库
复制链接
扫一扫
分享
社区描述
C/C++ 工具平台和程序库
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章