如何在队列内存分配失败后阻止调用其成员函数?
解决方案
1. 让构造函数在分配失败时重新抛出异常
原构造函数捕获std::bad_alloc后直接处理,导致无效的Queue对象被成功创建。正确的做法是不捕获异常,或者捕获后重新抛出,确保无效对象不会被实例化:
Queue(const int capacity){ arr = new int[capacity]; front = 0, rear = 0; this->capacity = capacity; }
如果需要保留错误提示再抛出:
Queue(const int capacity){ try{ arr = new int[capacity]; front = 0, rear = 0; this->capacity = capacity; } catch(const std::bad_alloc& ba){ cerr << "Failed to allocate memory for the queue!" << endl; throw; // 重新抛出异常,阻止对象创建 } }
此时用户必须用try-catch包裹Queue的创建逻辑,否则程序直接终止,从根源上避免无效对象被误用。
2. 引入状态标志+统一检查函数
如果必须允许对象存在但标记为无效,可以添加一个私有状态变量,配合统一的检查函数,在所有成员函数开头调用:
class Queue { private: int* arr = nullptr; int front, rear, capacity; bool isValid = false; // 标记对象是否有效 // 统一检查函数,私有且不可修改 void checkValidity() const { if (!isValid) { throw std::logic_error("Queue is invalid: memory allocation failed"); // 也可用断言:assert(isValid && "Cannot operate on invalid Queue"); } } public: Queue(const int capacity){ try{ arr = new int[capacity]; front = 0, rear = 0; this->capacity = capacity; isValid = true; // 分配成功后标记为有效 } catch(const std::bad_alloc& ba){ cerr << "Failed to allocate memory for the queue!" << endl; // 状态保持为false } } void enqueue(int val) { checkValidity(); // 调用统一检查 // 原有入队逻辑 if ((rear + 1) % capacity == front) { cerr << "Queue is full!" << endl; return; } arr[rear] = val; rear = (rear + 1) % capacity; } // 其他成员函数(dequeue、peek等)均在开头调用checkValidity() };
新增成员函数时只需调用一次检查函数,大幅减少重复代码。
3. 使用工厂函数返回智能指针
将构造函数设为私有,通过静态工厂函数创建对象,分配失败时返回空指针,确保用户拿到的要么是有效对象,要么是明确的无效标识:
#include <memory> class Queue { // 构造函数私有化 Queue(const int capacity) : front(0), rear(0), capacity(capacity) { arr = new int[capacity]; } public: static std::unique_ptr<Queue> create(int capacity) { try { return std::make_unique<Queue>(capacity); } catch (const std::bad_alloc& ba) { cerr << "Failed to allocate memory for the queue!" << endl; return nullptr; } } // 成员函数实现... };
用户使用时必须先检查指针有效性:
auto queue = Queue::create(1000000000); if (!queue) { // 处理分配失败,不执行队列操作 return; } queue->enqueue(5); // 仅有效对象可调用成员函数
内容的提问来源于stack exchange,提问作者Dzonex
相关产品推荐
相关产品推荐

