Pure Virtual Function Call






2.63/5 (17 votes)
Jul 20, 2006
2 min read

95501

192
How can you get the runtime error "Pure virtual Function Call" and how to avoid it
Clearing The Picture
One of the normal development day, a colleague came out of his desktop monitor (Yes, we spend our day working inside the monitor and rarely see others things :) ), saying “Pure virtual function call…How! How!”, We spend some time tracing until we concluded the following.
When an object contains a pure virtual function (a functions that is not implemented), then this object can’t be constructed at all and so the pure virtual function can’t be called all. Try the following code:
class Parent
{
public:
Parent()
{
}
~Parent()
{
ClearALL();
}
void ClearALL()
{
ThePure();
}
virtual bool ThePure() = 0 ;
};
void main()
{
Parent P;
/*error C2259: 'Parent' : cannot instantiate abstract class due to following members: Parent::ThePure(void)*/
}
Wait….It can be done…
So, how comes that a pure virtual function is called? To produce it, let’s continue our work and inherit a new class from Parent. Let’s call it Child. So, we have the following code:
class Parent
{
public:
Parent()
{
}
~Parent()
{
ClearALL();
}
void ClearALL()
{
ThePure();
}
virtual bool ThePure() = 0 ;
};
class Child : public Parent
{
public:
Child()
{
}
~Child()
{
}
/* The implementation of the pure virtual function */
virtual bool ThePure()
{
return true;
}
};
void main()
{
Child c;
}
Now, we are happy with the polymorphism we made and we run our program then we get the shock “Pure Virtual Function Call”.
To analyze that, let’s put an assumption that make a pure virtual function. To call the Function ThePure() but the version that is no implemented we should have an object from the class Parent and call the function throw it like:
Parent P;
P.ThePure(); //Compilation Error!
Which sure is impossible…but wait, it is possible. How????
We all know from Object-oriented concepts that when an object destructed, it destructor is called then the destructor of its parent and so on until we reach the first parent of the family, then the destruction process is done. So, if you reviewed the code above, you will see that in destructor of the parent, we call a function, which, in turn, calls a pure virtual function. This is legal to write in the code of the parent because at run time it is impossible to have an instance of it. Sure, the code will run in an object of type Child (because Parent can’t be constructed at all as we said). But at this moment (inside the Parent destructor), the child destructor is called and finished, so, we don’t have an object of type child now, but the current object (which is only being destructed) is of type Parent, so all calls in the destructor are calls to functions in this object. So, you can get a pure virtual function.
Compilers sometimes help
Now, the question you want to ask the code above is, why didn’t I call the pure virtual function in the destructor directly instead of Calling ClearAll() which in turn calls it. The answer is the happy news. It is that the Compiler is smart enough to detect such kind of errors (Why?) and issue a linking error. But if you called it indirectly like that, the compiler will be blind of the functions in the calls chain and get a pure virtual function.
I have compiled this code under VC++6.0 and VC++2003 and they made the same results.
Conclusion
So, to avoid this error, you should never call functions in the destructor, which calls functions those are not implemented in this object being destructed