【问题标题】:Priority Queue implemented by Vector using Abstract Class C++Vector使用抽象类C++实现的优先队列
【发布时间】:2015-02-27 00:02:47
【问题描述】:

我正在尝试使用 C++ 中的 Vector 模板实现优先级队列。我对 Java 最满意,并想模仿接口的想法,其中需要所有可以使用优先级队列的对象来实现某些方法。

我知道 C++ 不支持接口,但是,有人建议通过利用多重继承,这可以通过创建抽象类并需要一些虚函数来实现。

我想要所有可以使用优先队列的对象来实现:

public:
int compareTo(Comparable &obj);

这是一个实现此目的的 C++ 抽象类: 可比.h

class Comparable {
public:
    Comparable();
    ~Comparable();
    virtual int compareTo(Comparable &obj) = 0;
};

这很好用,将抽象类提供给 Vector 模板不会产生任何错误:

vector<Comparable> *mElements = new vector<Comparable>(); // no error

直到我尝试在从 Comparable 类继承的类中使用多态性时才遇到问题。因为方法签名收到一个 Comparable&,所以我无法访问扩展 Comparable 的类的成员:

int Event::compareTo(Comparable& obj) {
    // Min-Heap - time of currentObject is less than e.mTime
    Event e = (Event) obj; // Doesn't work - No C-style cast (can I make one and how?)
// if I trying obj.mTime, this won't work because it is not a member of the Comparable class


if (mTime < e.mTime) return Delta::NEGATIVE_CHANGE;
if (mTime > e.mTime) return Delta::POSITIVE_CHANGE;
    return return Delta::NO_CHANGE;
}

我需要做的只是比较这个例子中的时间,但我想设计这个类,以便客户端只需要从 Comparable 类继承并实现一个使用优先级队列的方法。

感谢任何高级帮助!

【问题讨论】:

  • ~Comparable(); -> virtual ~Comparable();,如果compareTo 需要知道obj 的具体类型,那么您的设计可能有问题。如果你确定这是你想要的,你可以使用dynamic_cast
  • C++ 不是 Java,多重继承是自取其辱的好方法。
  • @CollinDauphinee 我同意,最好的选择是使用运算符。他不需要类似的课程。
  • 确实,operator&lt; 是一个比抽象基类更 C++ 风格的解决方案,但更 C++ 风格和更灵活的解决方案是使用 functor 默认转至std::less,即STL有序容器的接口,如std::mapstd::set。但是,对于初学者来说,语法要复杂得多。

标签: c++ vector interface multiple-inheritance


【解决方案1】:

您正在搜索 dinamic_cast http://en.cppreference.com/w/cpp/language/dynamic_cast

dinamic_cast 有一个难看的名字,因为你不应该过多地使用它。在这种情况下,您不需要它。

首先,在 C++ 中,您可以重载运算符(、==...)。如果这些运算符不存在,则无法比较该类。比较自然和容易:)

其次,可以使用通用模板:

template<class T>
class Comparable {
public:
    Comparable();
    ~Comparable();
    virtual int compareTo(T &obj) = 0;
};

class event : public Comparable<event> {
    //...
    public:
        int compareTo(event &e) override;
};

你可以在编译时检测错误类型,你不需要在执行时强制转换:)

override 是编译器的一个 c++11 标志:“这个函数应该覆盖一个父函数,检查它”。不使用C++11的可以随意删除

【讨论】:

    【解决方案2】:

    实际上,如果PriorityQueue 类本身就是一个模板,那么您根本不需要Comparable 类。它将为实现 compareTo 的类型编译,而不会为未实现它的类型编译。

    template <class T>
    class PriorityQueue {
        ...
        void someMethod(const T& obj) {
            if (someOtherObj.compareTo(obj)) {
                ...
            }
        }
        ...
    }
    

    正如我之前在评论中所说,STL 有序容器使用 functors,而不是为其元素需要一些特定的接口。比使用 functor 更容易的是使用 &lt; 来比较对象:

    if (someOtherObj < obj) {
    

    Comparable 类实际上符合concept (C++14) 的理念,而不是抽象接口。它有助于阐明模板类/函数所需的接口是什么,但概念是 C++ 语言的一个非常新的特性,并未得到广泛支持,甚至不为人所知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多