如何对派生类进行等式测试

时间:2017-09-24 00:58:22

标签: c++

如何为派生类创建高效的equals方法?

struct Base {
    virtual bool equals(const Base &other) const = 0;
};

通常的答案是使用dynamic_casttypeid检查派生类中的类型标识,如果类型匹配则执行比较:

struct Derived: Base {
    virtual bool equals(const Base &other) const override {
        if (typeid(*this)!=typeid(other)) return false;

        return *this==static_cast<Derived &>(other);
    }
};

有更有效的方法进行此类型检查吗?如果我们禁用RTTI,我们该怎么办?

2 个答案:

答案 0 :(得分:1)

我认为核心问题是您不需要比较类型。这种需要总是表现出糟糕的设计,不正确的继承使用或其他糟糕的模式。

看看为什么你需要相等的信息 - 你打算用它来做什么 next 你不能通过调用类的onherited和覆盖方法来做?

答案 1 :(得分:0)

我从未见过这个“技巧”,所以我会在这里添加:

struct Base {
    virtual bool equals(const Base &other) const = 0;

    virtual const void *typeMarker() const = 0;
};

struct Derived: public Base {
    static char s_typeMarker;

    virtual bool equals(const Base &other) const override {
        if (&s_typeMarker!=other.typeMarker()) return false;

        return *this==static_cast<Derived &>(other);
    }

    virtual const void *typeMarker() const override {
        return &s_typeMarker;
    }
};

基本上,它有一个typeMarker()虚函数,它为每种类型返回一个唯一值。因此,使用虚函数调用(和比较)完成类型相等检查,这可能比typeiddynamic_cast便宜,并且此方法适用于禁用RTTI。

我知道唯一的缺点是这可能无法在.dlls中正常工作。

(基于这个答案,也许有人可以提出更好的解决方案。)