从基类调用重写的方法

Call overridden method from base class

本文关键字:方法 重写 调用 基类      更新时间:2023-10-16

在以下情况下如何从基类调用重写的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;
}

您不正确地将虚拟方法与派生对象绑定,从而对派生对象进行了切片。试试这个(* 被删除(

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

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

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

https://godbolt.org/z/pEs9ta

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