假设我有一个类型层次结构:
struct B { ... };
struct D1 : B { ... };
struct D2 : B { ... };
...
struct Dn : B { ... };
每个Di都有自己的operator==
定义:
struct Di : B
{
bool operator==(const Di&) const { ... }
...
};
我现在要定义B operator==
,以便:
struct B
{
bool operator==(const B& that) const
{
// psuedo-code
let i, such the dynamic type of this is Di
let j, such the dynamic type of that is Dj
if (i != j)
return false;
else
return Di::operator==(this, that);
}
}
组织这个或写这个的最佳方法是什么?
(最终目标是我想使用值类型为B *的标准容器类型(例如std::set<B*>
),但是当它们来自时,它使用自定义Di::operator==s
相同的派生类)
答案 0 :(得分:6)
在基类中定义受保护的虚函数。使其成为纯虚拟,以确保每个子类Di
提供实现。该函数将知道强制转换的目标,因为它属于Di
。从基类中的运算符==
调用该函数,并让它执行比较,如下所示:
struct B {
bool operator==(const B& that) const {
return this->equals(that);
}
protected:
virtual bool equals(const B& other) const=0;
};
struct D1 {
protected:
virtual bool equals(const B& other) const {
D1 *that = dynamic_cast<D1*>(&other);
if (!that) return false;
// Perform D1-specific comparison here.
// You can use the == operator of D1, but you do not have to:
return (*this) == (*that);
}
};
此构造的作用是使==
运算符虚拟的实现。
答案 1 :(得分:1)
以下是dasblinkenlight solution的略有变化,附加了功能(例如代码重复次数减少)
#include <typeinfo> // for typeid
struct B {
bool operator==(const B& that) const {
if (this == &that) // trivially equal
return true;
if (typeid(*this) != typeid(that)) // trivially different
return false;
return equals(that); // delegates to the virtual function
}
// polymorphic classes must have virtual destructors
virtual ~B() = default;
protected:
virtual bool equals(const B& that) const = 0;
};
struct D1 : B {
bool operator ==(const D1& that) const {
// ...
}
private:
// private because this function is not meant to be called except through
// B::equals
bool equals(const B& that) const override {
// static_cast is safe here because execution only gets here if the
// dynamic type of that is D1 (this was tested in B::operator =()
return *this == static_cast<const D1&>(that);
}
};