Click to See Complete Forum and Search --> : virtual function question


Cadiolis
September 13th, 2002, 02:20 PM
Say you have a class named 'Parent' with a virtual function called 'vfunction'. This virtual function only has full implementation in child classes. Now, in the destructor of the Parent function it calls the 'vfunction' function. Since the function is a virtual function, should the function be executed in the child class? This is not what is happening and I can only assume that it is illegal to do so.

The obvious solution would be to remove the desired code from the destructor and create a new virtual function and then call that function just before the destructor. It would be nice if I didn't have to do this, though, as it means placing the same code throughout the child classes (an OOP violation)

Am I correct that this is not possible?

proxima centaur
September 13th, 2002, 02:48 PM
No.

The parent class has no knowledge of the children methods. It assumes you want to call the Parent::vfunction method, not the Child::vfunction method that it doesn't know of.

Cadiolis
September 13th, 2002, 02:53 PM
Here is the appropriate code:

parent.h
-----------
virtual BOOL SaveAppInfo() = 0;

child1.h/child2.h/etc...
----------------
virtual BOOL SaveAppInfo();

child1.cpp/child2.cpp/etc...
----------------
BOOL Child1::SaveAppInfo() {
....
return TRUE;
}


I cannot compile this code. I get an unresolved symbol for SaveAppInfo. All examples on the net follow this format. Why doesn't it compile?

As for my original problem, this is the code in the parent destructor:

in parent.cpp destructor
----------------
SaveAppInfo();


proxima centaur: So pure virtual functions aren't smart enough to call the correct child function?

PaulWendt
September 13th, 2002, 02:59 PM
You persist with this. proxima centaur was correct; a base-class
destructor cannot call base-class virtual functions. Here's why.
An object is usually created in this order:
Base->DerivedClass.
Objects are destroyed in the opposite order:
DerivedClass->Base.
Thus, by the time you're in Base's destructor, DerivedClass does
not exist. Therefore, you're ONLY calling Base's member function.
Since you have it as pure virtual, you won't have anything get
called.

--Paul

jfaust
September 13th, 2002, 03:10 PM
Everybody here is correct. Don't call virtual methods from destructors. I have nothing to add on that topic.

However:

The obvious solution would be to remove the desired code from the destructor and create a new virtual function and then call that function just before the destructor.


If you are considering this to fix the problem, you are going about it the wrong way. There is surely something wrong with your design. I'd take a long hard look at where that real problem is and fix it there, rather than putting a bandage on this.

Jeff

proxima centaur
September 13th, 2002, 03:31 PM
I realize I wasn't too clear on my post. :eek:

You CAN call any method implemented in the children classes from a base class. By implemented I mean they are not pure virtual.

However the exceptions are:

You cannot call children methods from

- Base Class Contructors
- Base Class Destructors
- methods called by either Base Class cTor or dTor

There reason for this is exactly what Paul said. The order of creation destruction prevents this to work.


Why do you need to call a method of the children classes from the Base class dTor? Can't you do the same from the children's dTor, calling the intended method?

Just an idea.

Cadiolis
September 13th, 2002, 04:13 PM
Originally posted by jfaust
However:

If you are considering this to fix the problem, you are going about it the wrong way. There is surely something wrong with your design. I'd take a long hard look at where that real problem is and fix it there, rather than putting a bandage on this.
Jeff

Yeah, I found it just after I posted :rolleyes:

proxima centaur
Why do you need to call a method of the children classes from the Base class dTor? Can't you do the same from the children's dTor, calling the intended method?

Because of an unfortunate implementation by the folks at Palm. I found the correct solution anyways. Thanks for the help, though. The answer of 'not being able to do it from destructors' is the one I was looking for.