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

如何在C++中为两个类复用堆代码,避免重复实现

问题根源

你的vector<Job> heap直接存储抽象类Job的对象,而抽象类无法被实例化;同时即使Job不是抽象类,直接存储对象会触发对象切片,丢失子类的多态特性,导致无法调用子类的getValue和setValue实现。

解决方案一:用智能指针存储多态对象

将HeapStruct中的容器改为存储智能指针(推荐unique_ptr),既能保留多态特性,又能避免内存泄漏:

修改HeapStruct核心代码:

#include <memory> // 引入智能指针头文件

class HeapStruct{
private:
    vector<unique_ptr<Job>> heap; // 替换为智能指针容器
    long long size;
    long long maxSize;
    // ...其他私有成员

public:
    HeapStruct(long long maxSize) : maxSize(maxSize), size(0) {
        heap.reserve(maxSize); // 预分配空间
    }

    long long getValueAt(long long i) {
        return heap.at(i)->getValue(); // 通过指针调用虚函数
    }

    // 插入节点:接收子类的智能指针
    void insertNode(unique_ptr<Job> job) {
        if (size >= maxSize) return;
        heap.push_back(move(job));
        siftUp(size);
        size++;
    }

    // 获取最小值:返回智能指针
    unique_ptr<Job> getMin() {
        if (size == 0) return nullptr;
        return move(heap[0]);
    }

    // 堆上浮逻辑适配指针调用
    void siftUp(long long i) {
        while (i > 0) {
            long long parent = (i - 1) / 2;
            if (heap[i]->getValue() >= heap[parent]->getValue()) break;
            swap(heap[i], heap[parent]);
            i = parent;
        }
    }
    // siftDown/removeNode等操作同理,均改为通过指针调用虚函数
};

使用示例:

// 创建AvailableJob堆
HeapStruct availableHeap(100);
availableHeap.insertNode(make_unique<AvailableJob>(10, 20));

// 创建UsedJob堆
HeapStruct usedHeap(100);
usedHeap.insertNode(make_unique<UsedJob>(10, 20));
更优方案:用自定义比较器替代继承

无需修改原Job类结构,也不需要子类,直接给HeapStruct传入"取值逻辑",实现基于不同字段的排序,灵活性更高:

修改HeapStruct为带自定义逻辑的版本:

#include <functional> // 引入function头文件

class HeapStruct{
private:
    vector<Job> heap;
    long long size;
    long long maxSize;
    function<long long(const Job&)> getTargetValue; // 存储获取排序字段的函数

public:
    // 构造函数传入取值逻辑
    HeapStruct(long long maxSize, function<long long(const Job&)> func) 
        : maxSize(maxSize), size(0), getTargetValue(func) {
        heap.reserve(maxSize);
    }

    long long getValueAt(long long i) {
        return getTargetValue(heap.at(i));
    }

    void insertNode(const Job& job) {
        if (size >= maxSize) return;
        heap.push_back(job);
        siftUp(size);
        size++;
    }

    // 堆上浮逻辑基于自定义取值函数
    void siftUp(long long i) {
        while (i > 0) {
            long long parent = (i - 1) / 2;
            if (getTargetValue(heap[i]) >= getTargetValue(heap[parent])) break;
            swap(heap[i], heap[parent]);
            i = parent;
        }
    }

    Job getMin() {
        if (size == 0) throw runtime_error("Heap is empty");
        return heap[0];
    }
    // ...其他堆操作
};

使用示例:

// 基于value1的最小堆
HeapStruct heapByValue1(100, [](const Job& job) { return job.value1; });
heapByValue1.insertNode(Job(5, 10));

// 基于value2的最小堆
HeapStruct heapByValue2(100, [](const Job& job) { return job.value2; });
heapByValue2.insertNode(Job(5, 10));

这种方案避免了继承带来的耦合,同时支持快速扩展更多排序字段。

内容的提问来源于stack exchange,提问作者ad_valle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 08:45:10