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

Fra*_*ank 3 c++ equality operator-keyword

virtual operator==Base班上定义了一个.但出于某种原因,它似乎并没有真正被视为虚拟.

请参阅此示例代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*cia 6

问题是你实际上没有覆盖,operator==因为原来的签名不同.让我们通过使用一个有用的C++ 11特性来证明override:

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

使用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 {
Run Code Online (Sandbox Code Playgroud)

要解决这个问题,只需修改Derive's,operator==使其具有与s 相同的签名Base:

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

无论何时可以使用override,您都可以使编译器检测到这些类型的错误.