How to call overridden bar method from base class in the following scenario?
There is requirement that callback should always call method foo which should call bar which is overridden by latest derived class.
#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;
}
You are binding the virtual method with the derived object improperly, slicing the derived object. Try this (* is removed)
Base(Base *ptr){
callback = std::bind(&Base::foo, ptr);
}
An alternative method that avoids std::bind() altogether:
Base(Base *ptr){
callback = [this]() { foo(); };
}
https://godbolt.org/z/pEs9ta
Note that this requires at least C++11.
Related
This is purely a theoretical question. I don't have a particular use case in mind.
Can the virtuality of a C++ function be suppressed somewhere down the class hierarchy, or is it that once a virtual function is defined in a base class, it remains virtual down the rest of its class hierarchy?
I wrote some sample code where I was attempting to suppress the virtuality of a method defined up the class hierarchy but I did not succeed. My sample code follows:
class Base {
public:
virtual void myFunc() {
std::cout << "myFunc in Base" << std::endl;
}
};
class Child : public Base {
public:
void myFunc() {
std::cout << "myFunc in Child" << std::endl;
}
};
class GrandChild : public Child {
public:
void myFunc() {
std::cout << "myFunc in GrandChild" << std::endl;
}
};
int main() {
Base* ptr = new GrandChild();
ptr->myFunc();
return 0;
}
The output is as follows:
myFunc in GrandChild
One thing you can do is create a member with a different signature (even using defaulted arguments).
That is:
struct Base
{
virtual void foo()
{
std::cout << "Base::foo" << std::endl;
}
};
struct Derived : Base
{
void foo(int = 0)
{
std::cout << "Derived::foo" << std::endl;
}
};
...
Base * ptr = new Derived;
ptr->foo(); // will invoke Base::foo()
Here is some sample code:
#include <iostream>
class A {
public:
virtual void foo() {
std::cout << "base" << std::endl;
}
A() {
foo();
}
};
class B : public A {
int a;
public:
void foo() {
std::cout << "derived" << std::endl;
}
B(int a) :
a(a) {}
};
int main() {
B o(1);
return 0;
}
I want foo() to get called every time some A derived object is constructed. I do not want to call foo() explicitly in every derived class constructor.
Is there a way to do this in some elegant way?
There is no way you can call an overridden foo() from a base class constructor, no matter what you do. When the base class constructor is called, the derived class object has not been constructed yet, so you cannot call any of its methods or access any of its members. This is true for virtual functions and regular functions as well. In a base class constructor, the this pointer is pointing at the base class, not the derived class.
A potential workaround is to delegate construction to a separate function that clients will have to call instead. Then have that function call foo after construction:
class A {
public:
virtual void foo() {
std::cout << "base" << std::endl;
}
template<typename T, typename ... Args>
static T construct(Args ... args)
{
T newT{ args... };
newT.foo();
return std::move(newT);
}
protected:
A() {
//Construct A
}
};
class B : public A {
int a;
public:
void foo() {
std::cout << "derived" << std::endl;
}
B(int a) :
a(a) {}
};
int main()
{
B o = A::construct<B>(1);
A a = A::construct<A>();
return 0;
}
class Base
{
virtual void Foo(){}
virtual void Bar(){}
};
class Derived1 : public Base
{
void Foo(){ //Do something }
void Bar(){ //Do something }
}
class Derived2 : public Base
{
void Foo(){ //Do something }
void Bar(){ //Do something }
}
class OtherClass
{
public:
Base* obj;
void (Base::*method)();
void Add( Base* _obj, void (Base::*_method)() )
{
obj = _obj;
method = _method;
}
void Run()
{
( obj->method )();
}
}
int main()
{
Derived1 d1;
Derived2 d2;
OtherClass other;
other.Add( &d1, &(Derived1::Foo) );
//other.Add( &d2, &(Derived2::Bar) ); etc, etc.
other.Run();
}
My question:
Say I have a derived class with a method, I can refer to an instance of that class with a pointer of it's base type. Assuming I know what method I want to call, I can then call it via that pointer and the derived class's method will be called.
How can I achieve similar polymorphic behaviour when I specify the method to be called by supplying a method pointer?
The real code the above is based on will compile if I cast the method pointer, but it appears to not be doing any-- It is at this point I've realised I wasn't calling OtherClass's update method, which is why I wasn't getting any joy. :D So this works, as is (almost). Stupid, stupid brain.
Slight course correction then: Right now I need to static cast the method pointer I pass to OtherClass, to a pointer to Base class method when I pass it to Add. This is not ideal.
Can I get the same behaviour if I pass &(Base::Foo), for example, to the method Add?
Will Derived1::Foo be called if I invoke that method on a pointer to base type that refers to an instance of the derived type?
I get the feeling it'll call the base member. :(
Some reading:
Is it safe to "upcast" a method pointer and use it with base class pointer?
C++ inheritance and member function pointers
Pointer to member conversion
Casting a pointer to a method of a derived class to a pointer to a method of a base class
i believe you're pondering whether a member-fn-ptr of a virtual base will fire the polymorphic derivation override if provided in a derived class. If so, the answer is yes, and the code below demonstrate this.
Hope this helps.
#include <iostream>
class Base
{
public:
virtual void Foo()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
virtual void Bar()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
class Derived1 : public Base
{
public:
void Foo()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
void Bar()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
class Derived2 : public Base
{
public:
void Foo()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
void Bar()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
};
class OtherClass
{
public:
Base* obj;
void (Base::*method)();
void Add( Base* _obj, void (Base::*_method)() )
{
obj = _obj;
method = _method;
}
void Run()
{
(obj->*method)();
}
};
int main()
{
Derived1 d1;
Derived2 d2;
OtherClass other;
other.Add( &d1, &Base::Foo );
other.Run();
other.Add( &d2, &Base::Bar);
other.Run();
}
Output
virtual void Derived1::Foo()
virtual void Derived2::Bar()
Why was destructor of Derived class called in this code?
#include <iostream>
class Base
{
public:
Base() { std::cout << "Base::Base() \n"; }
~Base() { std::cout << "Base::~Base() \n"; }
};
class Derived : public Base
{
public:
Derived() { std::cout << "Derived::Derived() \n"; }
~Derived() { std::cout << "Derived::~Derived() \n"; }
};
Derived foo() { return Derived(); }
int main()
{
const Derived& instance = foo();
}
Why was destructor of Derived class called in this code?
Because the Derived instance created in foo() is going out of scope at the end of main program.
#include <iostream>
using namespace std;
class Base {
public:
Base() {
std::cout << "Base::Base() \n";
}
~Base() {
std::cout << "Base::~Base() \n";
}
};
class Derived: public Base {
public:
int i;
Derived() {
i = 10;
std::cout << "Derived::Derived() \n";
}
~Derived() {
i = 0;
std::cout << "Derived::~Derived() \n";
}
int get() {
return i;
}
};
Derived foo() {
return Derived();
}
int main() {
const Derived& instance = foo();
cout << instance.i << endl;
return 0;
}
The output is as follows:
Base::Base()
Derived::Derived()
10
Derived::~Derived()
Base::~Base()
To make it more interesting, consider a modified main:
const Base& instance = foo();
That code creates a temporary (the object returned by foo) of type Derived and extends the lifetime of the object by binding it to a constant reference of type Base. The lifetime of the temporary will be extended until the reference goes out of scope at which point the object will get destroyed. The code is roughly translated to:
Derived __tmp = foo();
const Base& instance = __tmp;
At the end of the block holding the reference instance, the __tmp variable also goes out of scope and gets deleted. Note that even with no virtual destructor, the appropriate destructor is called, as __tmp is of type Derived (the type returned by the function).
using C++, I have
struct Base {
virtual void stuff(/*base stuff*/);
};
struct Derived : public Base {
void stuff(/*derived stuff*/);
};
void function1(Derived& obj){
obj.stuff();
}
In this scenario, function1 will use Derived's do() function. What if in function1, I want to call the Base class's do() function instead ? Will it work if I call function1 as
function1(dynamic_cast<Base*>(derived_obj_ptr))?
After correcting the multitude of errors in your code, this is indeed achievable:
#include <iostream>
class Base {
public:
virtual void foo() { std::cout << "Base\n"; }
};
class Derived : public Base {
public:
void foo() { std::cout << "Derived\n"; }
};
void function1(Derived *p) {
p->Base::foo(); // <<<<< Here is the magic >>>>>
}
int main() {
Derived d;
function1(&d);
}
Output:
Base
(see http://ideone.com/FKFj8)