You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在队列内存分配失败后阻止调用其成员函数?

解决方案

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:18:29