Abstract functions

I have a solid background in Object Pascal and C++ is very new to me.

I have a base class that needs to call a function that is defined in a derived class. The function is declared as abstract in the base class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <new>
using namespace 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";
  }

  virtual void GetClassName()=0;

}; // end of baseClass

// derived class
class buttonClass : public baseClass {
  public:
  virtual void GetClassName(){cout<<"buttonClass";}
}; // end of buttonClass

int main () {

  baseClass* obj;    // base-class pointer

  obj = new buttonClass();
  obj->PrintClassName();
}

Running the above results in:
1
2
3
pure virtual method called
terminate called without an active exception
Class name is Aborted

Is what I am trying to do possible in C++?
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.")

Last edited on
Here's a link explaining the issue:
http://www.artima.com/cppsource/nevercall.html

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.

Edit: damn you Moschops, beat me by 2 mins :P
Last edited on
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:
 
virtual void GetClassName(){};

This way, if it is redefined inside a derived class, that version will be used instead.

EDIT: I was wrong.
Last edited on
Edit: damn you Moschops, beat me by 2 mins :P


Nin-JAAAAARRRR!
Thanks for the info. I'll stop trying to make the impossible work.
Topic archived. No new replies allowed.