虚拟调用基类方法

我想使用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_objA并使用&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应该更清洁。

链接地址: http://www.djcxy.com/p/35461.html

上一篇: virtual call to base class method

下一篇: Java Manual Validation after Argument Resolver