i have a problem in properly handling method overriding where an abstract class is present
inside my classes hierarchy.
I'll try to explain:
class AbstractClass{
public:
virtual void anyMethod() = 0;
};
class A : public AbstractClass {
void anyMethod() {
// A implementation of anyMethod
cout << "A";
}
};
class B : public AbstractClass {
void anyMethod() {
// B implementation of anyMethod
cout << "B";
}
};
AbstractClass *ptrA, *ptrB;
ptrA = new A();
ptrB = new B();
ptrA->anyMethod(); //prints A
ptrB->anyMethod(); //prints B
Ok..previous example work fine .. the concrete implementation of the AbstractClass
method anyMethod will be called at run time.
But AbstractClass is derived from another base class which has a method not virtual
called anyMethod:
class OtherClass {
public:
void anyMethod() {
cout << "OtherClass";
}
};
class AbstractClass : public OtherClass {
public:
virtual void anyMethod() = 0;
};
//A and B declared the same way as described before.
Now , if i try something like that:
ptrA = new A();
ptrB = new B();
ptrA->anyMethod(); //prints OtherClass
ptrB->anyMethod(); //prints OtherClass
What am I misunderstanding?
Is there any solution for making ptrA and ptrB printing A and B without using cast, typeid, etc?
Why don't you do:
class OtherClass
{
public:
virtual void anyMethod()
{
cout << "OtherClass";
};
}
That should solve your problems
If anyMethod
was declared virtual in the base class to which you have a pointer or reference, it should be looked up virtually and print A and B correctly. If it wasn't, then there is nothing you can do (beyond changing it to be virtual).
I think that if the method in OtherClass
that you want to override in A
and B
is NOT virtual, then the override is not implicit.
I believe there's a way to Explicitly override the functions, look that up.
DeadMGs answer is of course correct. But, if you cannot change OtherClass
Methode (e.g. it's from a third party lib) you might want to try this:
Are the pointers ptrA
and ptrB
of type OtherClass
or AbstractClass
in your lower example?
If they are OtherClass
I would expect the behaviour you described. You could try casting the pointer to AbstractClass
then:
dynamic_cast<AbstractClass*>(ptrA)->anyMethod();
As far as I can see from your code OtherClass::anyMethod()
is not a virtual and already implemented. It should work as you described if you define it as virtual
I think that your declaration for the second case is:
OtherClass* ptrA; and not AbstractClass *ptrA;
if you declared like the first case , there's no problem because the method is virtual,but if you declare as OtherClass , the compiler will not find virtual and bind to the adress of this method without using vtble.
thanks for the answers.. helped me a lot to understand the problem.
In effect I posted some wrong code, because i was misunderstanding the real problem.
Anyway, i think i partially solved my problem.
Here's the code:
#include <iostream>
`` using namespace std;
class Other{
public:
void foo(){
cout << "Other\n";
}
void foo(int a){}
};
class Abstract : public Other{
public:
virtual void foo() {};
virtual void foo(int c){
Other::foo(c);
}
};
class A : public Abstract{
public:
void foo(){
cout << "A\n";
}
};
class B : public Abstract{
public:
void foo(){
cout << "B\n";
}
};
int main(){
cout << "main\n";
Abstract * ptrA = new A();
Abstract * ptrB = new B();
Other *o = new Other();
o->foo();
ptrA->foo();
ptrB->foo();
ptrB->foo(3); //can't no more use the method foo with different signatures implemented in the base class Other, unless I explicitly redefined in the class Abstract
dynamic_cast<Other*>(ptrB)->foo(3);//can't dynamic_cast from derived to base
I was making two errors:
In my real code (not the simplified version posted before) i forgot to declare virtual
the function foo()
Even declaring virtual wasn't enough. In fact all the implementations of that function must be wrapped inside the class Abstract to become visible to the subclasses A and b. Otherwise wont't compile.
I don't know if it could be a clean solution..in fact that way I need to wrap all foo method signatures.