从基类调用重写的方法

时间:2020-05-14 18:24:14

标签: c++

在以下情况下如何从基类中调用重写的bar方法?

有一项要求,回调应始终调用方法foo,该方法应调用bar,该方法被最新派生类覆盖。

#include <iostream>
#include <functional>
#include <typeinfo>

using namespace std;

std::function<void(void)> callback = nullptr;

class Base {
 public:
  Base(Base* ptr) { callback = std::bind(&Base::foo, *ptr); }

  virtual ~Base() {}

  virtual void foo() {
    bar();  // How call foo() from Derived instead of Base?
  }
  virtual void bar() { cout << "Base::bar" << endl; }
};

class Derived : public Base {
 public:
  Derived() : Base(this) {}

  virtual void bar() override { cout << "Derived::bar" << endl; }
};

int main() {
  cout << "Hello World" << endl;
  Base* b = new Derived();

  cout << "**callback**" << endl;
  callback();  // output should be 'Derived::bar'

  return 0;
}

2 个答案:

答案 0 :(得分:4)

您将虚拟方法与派生对象绑定不正确,将派生对象切片。试试这个(*已删除)

Base(Base *ptr){
    callback = std::bind(&Base::foo, ptr);
}    

答案 1 :(得分:1)

一种完全避免使用std::bind()的替代方法:

Base(Base *ptr){
        callback = [this]() { foo(); };
    }

https://godbolt.org/z/pEs9ta

请注意,这至少需要C ++ 11。