QueueVec类const Head()函数在默认构造空队列下异常求助
问题:const版本Head()调用默认构造空队列时陷入无限循环
现象
- 非const版本
Head()调用默认构造的空队列,能正常抛出std::length_error并被捕获 - const版本
Head()调用默认构造的空队列时,程序陷入无限循环,连Const Head的输出都无法打印 - 非默认构造的队列调用const版本
Head()工作正常
原因分析
核心问题出在拷贝构造函数与拷贝赋值函数的循环调用:
当测试代码执行HeadTestHelp( (const Que ) coda );时,会创建一个临时的const QueueVec对象,触发拷贝构造函数。如果你的拷贝构造函数实现是通过调用拷贝赋值(如*this = other;),而拷贝赋值函数又通过创建临时对象(copy-and-swap idiom)调用拷贝构造函数,就会形成无限递归,导致程序陷入无限循环,永远无法进入HeadTestHelp函数执行后续逻辑。
另外,默认构造函数直接覆盖基类Vector的size和vec成员,可能破坏基类内部状态,但这不是本次无限循环的直接原因。
修复方案
1. 正确实现拷贝构造函数
拷贝构造函数应直接初始化所有成员,避免调用拷贝赋值:
template<typename Data> QueueVec<Data>::QueueVec(const QueueVec& other) : Vector<Data>(other), front(other.front), rear(other.rear), countElements(other.countElements) {}
该实现先调用基类Vector的拷贝构造函数复制数组,再复制QueueVec自身的队列控制成员(front、rear、countElements)。
2. 正确实现拷贝赋值函数
可以直接赋值成员,或使用copy-and-swap idiom(需确保拷贝构造函数正确):
template<typename Data> QueueVec<Data>& QueueVec<Data>::operator=(const QueueVec& other) { if (this != &other) { // 调用基类的拷贝赋值 Vector<Data>::operator=(other); // 复制队列控制成员 front = other.front; rear = other.rear; countElements = other.countElements; } return *this; }
3. 优化默认构造函数
避免直接覆盖基类成员,改用基类构造函数初始化:
template<typename Data> QueueVec<Data>::QueueVec() : Vector<Data>(8), front(0), rear(-1), countElements(0) {}
该实现通过Vector的构造函数直接分配大小为8的数组,无需手动管理vec内存,更安全。
4. 测试代码的小修正
确保捕获异常时使用完整命名空间,并用引用捕获避免拷贝:
catch(const std::length_error& e) { std::cout << "Object is empty" << std::endl; }
内容的提问来源于stack exchange,提问作者Arteteca
相关产品推荐
相关产品推荐

