对两个类使用堆代码c++无需重写

8cdiaqws  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(65)

我尝试为两个不同的类实现堆代码,我不想重写堆代码,因为它已经工作(测试和工作)
所以我有了第一个(原始的)类,让我们称之为Job,它有几个属性。然后我将它修改为抽象的,并有两个类实现了这个Job类:

class Job {
protected:
    long long value1;
    long long value2;

    ...

public:
    Job(long long value1, long long value2) : value1(value1), value2(value2) {};
    virtual void setValue(long long value);
    virtual long long getValue();
};

class AvailableJob : public Job{

public:
    AvailableJob (long long value1, long long value2): Job(value1, value2) {};

    void setValue(long long value) {
        if (value == -1)
            return;
        value1 = value;
    }

    long long getValue() {
        return value1;
    }
};

class UsedJob : public Job{

public:
    UsedJob (long long value1, long long value2): Job(value1, value2) {};

    void setValue(long long value) {
        if (value == -1)
            return;
        value2 = value;
    }

    long long getValue() {
        return value2 ;
    }
};

字符串
类有更多的属性和方法,但这些与这个问题无关。
问题是,我使用HeapStruct类创建了两个最小堆树,但我希望一个最小堆使用value1作为引用值,另一个最小堆使用value2
所以我想这样会有用:

class HeapStruct{
    private:
        vector<Job> heap;
        long long size;
        long long maxSize;
...
    public:
    HeapStruct(long long maxSize) : maxSize(maxSize) {
    // initialize heap
    }
    long long getValueAt(long long i) {
        return heap.at(i).getValue();
    }
    
    void siftUp(long long i) {
        // siftUp using job::getValue and job::setValue methods
    }

    void siftDown(){};
    Job getMin(){};
    void insertNode(){};
    removeNode(){};
};


我认为使用Job::getValueJob::setValue方法就足够了,但是我如何告诉HeapStruct使用AvailableJobUsedJob。现在正在抱怨使用抽象类。
此外,如果这不是最好的方法,你知道一个更好的,我愿意尝试不同的东西。

ghg1uchk

ghg1uchk1#

类成员vector<Job> heap;只能存储Job,而不能存储派生类。如果你需要一个Job类型的容器,你可以让HeapStruct成为一个模板,与任何T一起工作:

template <class T>
class HeapStruct {
private:
        vector<T> heap;
        //...
public:
     T getMin();   // should  we really returning a copy here?
};

字符串
并且,可能在C20之前使用SFINAE,或者甚至在C20中将其限制为命名概念到Job派生类:

template <std::derived_from<Job> T>
class HeapStruct {


如果你必须为任何作业使用相同的类型,但不能将它们混合在一起,你可以在那里添加一个虚拟基类来执行类型擦除:

class HeapStructBase {
public:
   virtual Job& getMin() = 0;

   // just a cast, to get something like getMin<AvailableJob>()
   template<class V>  
   auto getMin() { return dynamic_cast<V&>(this->getMin()); }
};

template <std::derived_from<Job> T>
class HeapStruct : public HeapStructBase {
private:
        vector<T> heap;
public:
     T& getMin() override;   // T derived from Job
};

相关问题