I know this question must have been covered endless of times, but I've searched the previous questions, and nothing seems to pop.
It's about inheritance and virtual functions i C++. I have a problem with calling virtual functions in subclasses from the superclass.
Let me give an example. Start of with three classes, which inherit from each other.
class A {
void foo() { bar() }
virtual void bar() { }
};
class B : public A {
virtual void bar() { }
};
class C : public B {
virtual void bar() { // do something }
};
Now I wanna have a variable declared as B* but instantiated as C*.
B* myObject = new C();
myObject->foo();
When I do this, and call foo() on myObject, then A::foo() is calling bar(). But only B::bar() is called, not C::Bar() - which in reality myObject is, even though it's declared as B, which again affects that "// do nothing" doesn't get executed.
How do I tell A::foo(), that it needs to look at lowest implementation?
Makes sense?
// Trenskow
EDIT:
C::Foo is not the problem. Foo is being called in class A, as it's the only place it's implemented. The problem arises, when A:Foo calls Bar(). Then B:Bar is called and not C::Bar.
Maybe the problem is, that in my implementation, I only get a void* pointer to the object in A.
Like this:
void A:Foo(void *a) {
A* tmpA = static_cast<A*> (a);
tmpA->bar();
}
Now the compiler thinks, that tmpA is an A. But somehow it manages to figure that it's a B*, and calls B::Bar, when in fact tmpA is a C* and it should be calling C::Bar.
The following prints "A::foo C::bar" as expected. Are you getting something different? B::bar
is never called because C
is the actual runtime type of the object. In C::bar
, you could call B::bar
explicitly by adding B::bar();
to its body.
#include <iostream>
using namespace std;
class A {
public:
void foo() { cout << "A::foo "; bar(); }
virtual void bar() { }
};
class B : public A {
public:
virtual void bar() { cout << "B::bar" << endl; }
};
class C : public B {
public:
virtual void bar() { cout << "C::bar" << endl; }
};
int main()
{
B* c = new C();
c->foo();
return 0;
}
void A:Foo(void *a) {
A* tmpA = static_cast<A*> (a);
tmpA->bar();
}
This is undefined behaviour. You cannot cast a B* to a void*, then cast that void* back to an A*. If you want it to work properly, you have to ditch the void*. Alternatively, you could try dynamic_cast.
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