#include <iostream>
#include <new>
usingnamespace std;
// abstract base class
class baseClass {
public:
baseClass(){
PrintClassName();
}
void PrintClassName(){
cout<<"Class name is ";
GetClassName(); // This is the call to the function in the derived classes
cout<<"\n";
}
virtualvoid GetClassName()=0;
}; // end of baseClass
// derived class
class buttonClass : public baseClass {
public:
virtualvoid GetClassName(){cout<<"buttonClass";}
}; // end of buttonClass
int main () {
baseClass* obj; // base-class pointer
obj = new buttonClass();
obj->PrintClassName();
}
The issue is that you're calling PrintClassName() in the constructor of the base class. When that gets executed during construction of the derived, it essentially "thinks" itself to be an object of type base, so you hit the problem.
If you remove it from the constructor, all will be fine and the derived function will be called in the derived object call to PrintClassName().
This is explicitly covered by Meyers here: http://www.artima.com/cppsource/nevercall.html (Meyers, 3rd edition, Item 9: "Never call virtual functions during construction or destruction.")
The short of it, during object construction, the first step is to call any base class constructors, then initialize data members of the derived class, and finally do anything inside the derived class's constructor. So when you are calling the base class constructor, the derived class (and its data members) has not yet been constructed - until that happens the object is not yet considered the derived class. In short, don't call virtual functions from constructors or destructors and expect polymorphism.
You declare "GetClassName" purely virtual by putting the "=0" at the end. This means that it has to be overridden in a derived class to be usable, but you won't be allowed to call it inside BaseClass itself, because you aren't guaranteed that it's been overridden. Instead, drop the purely virtual, and just declare it as an empty function:
virtualvoid GetClassName(){};
This way, if it is redefined inside a derived class, that version will be used instead.