c++ - C++ 比较器覆盖
问题描述
假设我有一个基类和多个派生类(将来可能会更多)。有没有办法覆盖派生类的比较器,或者达到相同的结果?
class Base {
public:
virtual bool operator==(const Base&) = 0;
};
class Version1 : public Base {
public:
bool operator==(const Derived&) {
// do something
}
};
class Version2 : public Base {
public:
bool operator==(const Derived&) {
// do something
}
};
// Could be more version derived class
int main() {
Base *obj1 = new Version1;
Base *obj2 = new Version1;
std::cout << (*obj1 == *obj2) << std::endl; // is there a way to do so?
}
具体来说,任何子类都可以与没有宏和 dynamic_castBase
的任何其他子类相媲美。Base
解决方案
不幸的是,C++ 不支持多动态调度,因此无法直接执行此操作——您最终需要使用 dynamic_cast 并在比较函数中进行额外检查:
class Base {
public:
virtual bool operator==(const Base&) const = 0;
};
class Version1 : public Base {
public:
bool operator==(const Base &b) const {
if (auto *a = dynamic_cast<Version1 *>(&b)) {
if (typeid(*this) != typeid(*a)) {
// `a` is some other class derived from Version1
return false; }
// compare fields of *this and *a for equality
return f1 == a->f1 && f2 == a->f2 && ...
}
return false;
}
一个棘手的部分是typeid
测试,只有在将来可能有其他从 Version1 派生的类时才需要它。如果它是 final ( class Version1 final : public Base
...) 则不需要 typeid 测试。
另一个细节是const
关于operator==
函数的——你几乎总是想要这样,所以你可以比较(与)右值或常量。
推荐阅读
- intellij-idea - Intellij 使用 JAXB 生成 java 代码返回 xsd 文件
- html - 我无法通过边框工作在我的 div 中获取此文本
- swift - Swift 将按钮动态添加到 UIScrollView 但它不能滚动,为什么?
- java - 为什么我在 Firebase 上注册新用户失败?
- json - 路由没有定义?
- oracle - jdbc的sql脚本中连接用户名/密码@sid的选项是什么
- java - 在 Fragment 中返回后如何通过 URL 更改图像颜色
- r - R ggplot:如何格式化x轴以使第一个标签与后续标签不同
- firefox-addon - 无法与本机消息传递主机 (firefox) 通信
- jquery - 尝试使用 jQuery 预加载网页时出现“TypeError: e is null”