I want to use std::bind
and do non-virtual call to base class function eg: derived_obj.BaseClass::foo()
Example:
Let's say I have base class A and derived class B. A has a virtual function foo()
which is overridden by B.
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()!";}
}
If I want to call A::foo()
from object of class B I do non-virtual call:
B b_obj;
b_obj.A::foo(); // prints "Hello from A::foo()!"
Now I want to use std::bind
and do non-virtual call to A::foo()
from b_obj, how do I do this?
I've already tried by casting b_obj
to A and use address of &A::foo()
, but had no luck.
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()!"
You cannot override a non-virtual or static method. The overridden base method must be virtual , abstract , or override . An override declaration cannot change the accessibility of the virtual method. Both the override method and the virtual method must have the same access level modifier.
It is allowed and it's not a problem - and if you call the method directly as you have done it will be called fine. But, being non-virtual, C++ method lookup mechanisms that allow for polymorphism won't be used.
When you want to call a specific base class's version of a virtual function, just qualify it with the name of the class you are after, as I did in Example 8-16: p->Base::foo(); This will call the version of foo defined for Base , and not the one defined for whatever subclass of Base p points to.
So polymorphic behaviour works even when a virtual function is called inside a non-virtual function. The output can be guessed from the fact that the function to be called is decided at run-time using the vptr and vtable.
Calling a base class virtual function from a derived class September 8, 2016martin You can call a base class version of a virtual function from a derived class by prefixing its name with the name of the base class. For example, if you have the following base class:
You can call its version of method()within a derived class like this: class Derived : public Base { virtual void method() { Base::method(); std::cout << "Derived::method()" << " "; } virtual ~Derived() { } }; Example program:
When the method is declared as virtual in a base class, and the same definition exists in a derived class, there is no need for override, but a different definition will only work if the method is overridden in the derived class. By default, methods are non-virtual, and they cannot be overridden.
Virtual base classes offer a way to save space and avoid ambiguities in class hierarchies that use multiple inheritances. When a base class is specified as a virtual base, it can act as an indirect base more than once without duplication of its data members.
You have two options here. You should either do the non-virtual call in a lambda or you go the trusty old way of slicing the object (which is a copy) you want to pass to 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();
This all prints:
Hello from A::foo()!
Hello from A::foo()!
Hello from A::foo()!
The Second method works (slices) since std::bind
copies its arguments. You should really prefer a lambda.
You could wrap the call inside a lambda:
B b_obj;
auto f = std::bind([&b_obj]() { b_obj.A::foo(); } );
But this makes little sense unless you can only use std::bind
somewhere (for example because of std::is_bind_expression
), as you pass the object parameter to the lambda's capture, not to bind.
Otherwise just using a lambda or std::function
without bind
should be cleaner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With