虚拟调用基类方法
我想使用std::bind
并对基类函数进行非虚拟调用,例如: derived_obj.BaseClass::foo()
例:
假设我有基类A和派生类B。 A具有被B覆盖的虚拟函数foo()
。
class A
{
public:
virtual void foo() { std::cout << "Hello from A::foo()!";}
}
class B : public A
{
public:
void foo() overide { std::cout << "Hello from B::foo()!";}
}
如果我想从B类的对象中调用A::foo()
,我会进行非虚拟调用:
B b_obj;
b_obj.A::foo(); // prints "Hello from A::foo()!"
现在我想使用std::bind
并从b_obj对A::foo()
进行非虚拟调用,我该怎么做?
我已经尝试通过将b_obj
到A并使用&A::foo()
地址,但没有运气。
auto f = std::bind(&A::foo, static_cast<A*>(&b_obj));
f(); // prints "Hello from B::foo()!" but it should print "Hello from A::foo()!"
你有两个选择。 您应该在lambda表达式中执行非虚拟调用,或者采用可靠的旧方法对要传递给std::bind
的对象(这是一个副本)进行切片。
// Base method
B b_obj; b_obj.A::foo(); // prints "Hello from A::foo()!"
// First method
auto k = [](auto b){ b.A::foo(); };
k(b_obj);
// Second method
auto f = std::bind(&A::foo, *static_cast<A*>(&b_obj));
f();
这一切打印:
Hello from A::foo()!
Hello from A::foo()!
Hello from A::foo()!
第二种方法工作(切片),因为std::bind
复制它的参数。 你应该更喜欢lambda。
你可以把这个调用包装在一个lambda中:
B b_obj;
auto f = std::bind([&b_obj]() { b_obj.A::foo(); } );
但是,除非您只能在某处使用std::bind
(例如,因为std::is_bind_expression
),否则这没什么意义,因为您将对象参数传递给lambda的捕获,而不是绑定。
否则,只使用不带bind
的lambda或std::function
应该更清洁。