C++双栈实现Queue时两stack为空场景下的exception抛出问题
双栈实现队列的异常逻辑与功能修复
核心问题修复点
1. 异常抛出的正确写法
你当前的throw;是空抛出,只有在已经捕获到异常的catch块中重新抛出时才可以这么用,主动抛出自定义异常需要构造异常类的实例:
throw QueueEmptyException();
同时判空可以直接复用你已经实现的empty()方法(通过numElements判断),不用重复判断两个栈的状态,逻辑更统一。
2. 核心逻辑纠正
你当前的栈分工逻辑是反的,会导致队列顺序错误:
- 正确分工:
st1作为入队栈,所有新元素都推入st1;st2作为出队栈,只有st2为空时才把st1的所有元素倒到st2,此时st2的栈顶就是队头,保证FIFO特性。
3. front()方法优化
front()需要先判空抛异常,同时要处理st2为空的场景,先倒数据再返回栈顶。
4. 其他注意点
- 模板类的实现不能放在独立的
.cpp文件中,否则会出现链接错误,建议把实现直接写到头文件,或者在头文件末尾引入实现文件。 main函数中qfs.QueueFromStacks();是多余代码,对象声明时已经自动调用构造函数,显式调用构造会报错。QueueEmptyException的构造、析构函数需要实现,否则会出现链接错误。
完整修复代码
头文件 QueueFromStacks.h
#ifndef QUEUEFROMSTACKS_H_ #define QUEUEFROMSTACKS_H_ #include <iostream> #include <stack> #include <string> using namespace std; class QueueEmptyException{ public: QueueEmptyException(); ~QueueEmptyException(); string getMessage() { return "Queue is empty"; } }; template <typename E> class QueueFromStacks { public: QueueFromStacks(); ~QueueFromStacks(); int size() const; bool empty() const; const E& front() const throw(QueueEmptyException); void enqueue (const E& e); void dequeue() throw(QueueEmptyException); private: stack<E> st1; // 入队栈 stack<E> st2; // 出队栈 int numElements; }; // 模板实现直接放在头文件避免链接错误 template <typename E> QueueFromStacks<E>::QueueFromStacks() { numElements = 0; } template <typename E> QueueFromStacks<E>::~QueueFromStacks() {} template <typename E> int QueueFromStacks<E>::size() const { return numElements; } template <typename E> bool QueueFromStacks<E>::empty() const { return (size() == 0); } template <typename E> const E& QueueFromStacks<E>::front() const throw(QueueEmptyException) { // 先判空抛异常 if (empty()) { throw QueueEmptyException(); } // 出队栈为空则倒数据 if (st2.empty()) { while (!st1.empty()) { st2.push(st1.top()); st1.pop(); } } return st2.top(); } template <typename E> void QueueFromStacks<E>::enqueue (const E& e) { st1.push(e); numElements++; } template <typename E> void QueueFromStacks<E>::dequeue() throw(QueueEmptyException) { // 判空抛异常 if (empty()) { throw QueueEmptyException(); } // 出队栈为空则倒数据 if (st2.empty()) { while (!st1.empty()) { st2.push(st1.top()); st1.pop(); } } st2.pop(); numElements--; } // 实现异常类的构造和析构 QueueEmptyException::QueueEmptyException() {} QueueEmptyException::~QueueEmptyException() {} #endif /* QUEUEFROMSTACKS_H_ */
main函数
#include "QueueFromStacks.h" int main() { QueueFromStacks<int> qfs; qfs.enqueue(1); qfs.enqueue(2); qfs.enqueue(3); qfs.dequeue(); cout << "Queue Front : " << (qfs.front())<< endl; // 输出2 // 异常测试示例 try { QueueFromStacks<int> empty_q; empty_q.dequeue(); // 空队列出队,触发异常 } catch (const QueueEmptyException& e) { cout << "捕获异常:" << e.getMessage() << endl; } return 0; }
内容的提问来源于stack exchange,提问作者RoseSkull123
相关产品推荐
相关产品推荐

