Pure virtual question..

I was playing around with inheritance when I realized this results in a linker error regarding Test(). For some reason I thought this is valid code, so pure virtuals can only be called from derived classes?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base
{
public:
	Base(){}
	virtual ~Root(){ Test(); }
	virtual void Test() = 0;
};

class Trunk
{
public:
	Trunk(){}
	virtual ~Trunk(){}
	virtual void Test(){}
};

int main()
{
	Trunk TestTrunk;
	return 0;
}
I wonder if this might be a typo, but in your code Trunk does not inherit from Base. And you can't even instantiate a class with a pure virtual function (it becomes an abstract base class) so naturally you would have to derive from it to call it.
It's a bad idea to call virtual functions from ctors and dtors. Here's why:

When you create a Trunk object, the following happens in order:

1) 'Base' is constructed first
2) 'Trunk' is constructed AFTER Base's ctor is complete.
3) your Trunk object is now fully constructed (ie: safe to call virtual functions)
4) 'Trunk' is destructed
5) 'Base' is destructed


The thing to note here is that Trunk is destructed before Base. So by the time Base's dtor is run, Trunk has already been destucted. So if you call a virtual function that is implemented in Trunk... the 'this' pointer would point to a destructed object (ie: potential program explosion -- can't access members that no longer exist).

Therefore as a safeguard, this particular C++ implementation simply doesn't let you do this, and instead of actually calling the virtual function, it's just calling Base::Test... but since that's pure virtual it doesn't have a body, and therefore you get the linker error.
Last edited on
Well, no, you can call virtuals also from the base classes, as long as you define them. But this code doesn't seem to cause any linking problem, you defined them, as empty functions.
Well, no, you can call virtuals also from the base classes, as long as you define them.


It's different when you call from ctors/dtors. Since the object is not fully constructed yet (or is partially destructed already) in those functions, it is not safe to invoke functions defined in child classes, and therefore C++ doesn't let you do it.

But this code doesn't seem to cause any linking problem


I didn't actually test it, but he said it did =P

Plus it looks to me like it would. He's calling Base::Test and Base::Test has no body. Therefore it's a linker error.
It would also be valid for the program to link then crash with a pure virtual called error.
Topic archived. No new replies allowed.