c++ - 为什么virtual operator==是在Base类而不是Derived类上调用的?

标签 c++ operator-keyword equality

我在我的 Base 类中定义了一个 virtual operator==。但出于某种原因,它似乎并没有真正被视为虚拟。

查看示例代码:

#include <iostream>
#include <boost/unordered_set.hpp>

template<class T> struct EqualByValue {
  bool operator()(T const* a, T const* b) const { return *a == *b; }
};

struct Base {
  virtual bool operator==(Base const& other) const {
    std::cerr << "Base==" << std::endl;
  }
};

struct Derived : Base {
  virtual bool operator==(Derived const& other) const {
    std::cerr << "Derived==" << std::endl;
  }
};

int main(int argc, char** argv){
  typedef boost::unordered_set<Base*, boost::hash<Base*>, EqualByValue<Base> > 
    MySet;
  MySet s;
  Derived* d1 = new Derived();
  Derived* d2 = new Derived();
  s.insert(d1);
  s.insert(d2);
  s.find(d2);
  delete d1; delete d2; return 0;
}

输出是 Base== 而不是所需的输出 Derived==

这是为什么,我该如何解决?

最佳答案

问题是你实际上并没有覆盖 operator== 因为原来的有不同的签名。让我们通过使用称为 override 的有用 C++11 功能来演示:

struct Derived : Base {
  virtual bool operator==(Derived const& other) const override {
  //                                                  ^^^^^^^^
    std::cerr << "Derived==" << std::endl;
  }
};

Compiling it with GCC导致以下错误:

main.cpp:15:8: error: ‘bool Derived::operator==(const Derived&) const’ marked override, but does not override

   bool operator==(Derived const& other) const override {

要解决该问题,只需修改Deriveoperator== 使其具有与Base 的相同的签名:

struct Derived : Base {
  bool operator==(Base const& other) const override {
    std::cerr << "Derived==" << std::endl;
    // ...
  }
};

只要有可能,就使用override,这样您就可以让编译器检测到这些类型的错误。

关于c++ - 为什么virtual operator==是在Base类而不是Derived类上调用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19943791/

相关文章:

F# '+' 运算符重载和 List.fold

c# - 在非不可变类型中覆盖 == 运算符

java - 什么时候在 Java 中使用引用相等与对象相等比较合适?

c++ - 如何将函数对象作为回调c++传递给函数

c++ - 创建柯南 test_package 配方

oracle - Airflow Oracle 运算符(operator)

python - NumPy,为什么相等性检查不适用于对象数组?

c++ - 正确关闭 QMetaObject::Connection

c++ - 在这些例子中的哪个例子中转换是必要的?

c++ - 为什么为我的对象类编译标准优先级队列失败?