473,395 Members | 1,949 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Calling virtual functions from destructors?

Hi

I've had a problem with gcc mac osx which I think I figured out. I would
like to double check with people here to see if my understanding is correct:

I have a class A which class B inherit from. A has a pure virtual function
virtual in f1() = 0. In B I implement this function and the compiler works
out the code. However from A's destructor B can be compiled and then the
runtime aborts with saying that a call to a pure virtual function is not
allowed.

I'm assuming that B's destructor has been called before A's destructor and
thus it won't allow me to call the virtual function through the destructor.

The big question is what to do about this then? E.g. I have a class specific
cleanup method which is implemented with a GoF template pattern.

Thanks.

-- Henrik
Nov 19 '06 #1
6 5620
Henrik Goldman wrote:
Hi

I've had a problem with gcc mac osx which I think I figured out. I would
like to double check with people here to see if my understanding is
correct:

I have a class A which class B inherit from. A has a pure virtual function
virtual in f1() = 0. In B I implement this function and the compiler works
out the code. However from A's destructor B can be compiled and then the
runtime aborts with saying that a call to a pure virtual function is not
allowed.

I'm assuming that B's destructor has been called before A's destructor and
thus it won't allow me to call the virtual function through the
destructor.
More precisely, when the object is destroyed, B's destructor is called
first. After that finished, the object is not a B anymore. It's only an A
now. Since you don't have an implementation for f1() in A, you get into
trouble when trying to call it.
The big question is what to do about this then?
Depends on what you want to do.
E.g. I have a class specific cleanup method which is implemented with a
GoF template pattern.
Why?

Nov 19 '06 #2
There is no need to make CLeanUp method virtual. Make all your clean-up
routines in destructor. If you need to make it in separate method, just
write CleanUp method for every class and call it from destructor as in
example below:

#include <iostream>

class A
{
public:
A() { }
virtual ~A() { CleanUp(); }

virtual void VMethod() = 0;

private:
void CleanUp();
};

class B: public A
{
public:
B(): A() { }
virtual ~B() { CleanUp(); }

virtual void VMethod()
{
}

private:
void CleanUp();
};

void A::CleanUp()
{
std::cout << "A::CleanUp()\n";
}

void B::CleanUp()
{
std::cout << "B::CleanUp()\n";
}

int main()
{
A* instance = new B();
delete instance;
}

Nov 19 '06 #3
On Sun, 19 Nov 2006 15:13:46 +0100 in comp.lang.c++, "Henrik Goldman"
<he************@mail.tele.dkwrote,
>I'm assuming that B's destructor has been called before A's destructor and
thus it won't allow me to call the virtual function through the destructor.
Yes. It is the same during construction.

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[23.5] When my base class's constructor calls a virtual function on its
this object, why doesn't my derived class's override of that virtual
function get invoked?" and "[23.7] I'm getting the same mess with
destructors: calling a virtual on my this object from my base class's
destructor ends up ignoring the override in the derived class; what's
going on?". It is always good to check the FAQ before posting.
You can read the FAQ at: http://www.parashift.com/c++-faq-lite/
>The big question is what to do about this then? E.g. I have a class specific
cleanup method which is implemented with a GoF template pattern.
B's destructor should ordinarily take care of B-specific stuff.
If that's not enough, you need to be specific about what you are doing.
See also FAQ [23.6]

Nov 19 '06 #4
More precisely, when the object is destroyed, B's destructor is called
first. After that finished, the object is not a B anymore. It's only an A
now. Since you don't have an implementation for f1() in A, you get into
trouble when trying to call it.
Correct. It took me a little while to realise this but yes it's right.
>
>E.g. I have a class specific cleanup method which is implemented with a
GoF template pattern.

Why?
My intention is to create a class which uses RAII idiom. Upon destruction it
may need a algorithm specific way for destruction.

It's a class for handled spawning and closed processes. It is platform
independent and support several platforms. However on some unix platforms I
get weird results from fork/child and when I need to shut things down
politely I am sometimes closing the wrong pid. It's a platform specific
problem. However I have an application specific method which is 100%
fool-proof by getting the pid from a special pid file. Therefore I wanted
to create an inherited class to deal with my application specific algorithm.
However this technique backfired on me since I cannot obtain the algorithms
specific information at destruction time.
The only alternative I see is to call the destruction explicitly before
destruction time... but then RAII is pointless in this case.

-- Henrik
Nov 19 '06 #5

Henrik Goldman wrote:
More precisely, when the object is destroyed, B's destructor is called
first. After that finished, the object is not a B anymore. It's only an A
now. Since you don't have an implementation for f1() in A, you get into
trouble when trying to call it.

Correct. It took me a little while to realise this but yes it's right.
E.g. I have a class specific cleanup method which is implemented with a
GoF template pattern.
Why?

My intention is to create a class which uses RAII idiom. Upon destruction it
may need a algorithm specific way for destruction.

It's a class for handled spawning and closed processes. It is platform
independent and support several platforms. However on some unix platforms I
get weird results from fork/child and when I need to shut things down
politely I am sometimes closing the wrong pid. It's a platform specific
problem. However I have an application specific method which is 100%
fool-proof by getting the pid from a special pid file. Therefore I wanted
to create an inherited class to deal with my application specific algorithm.
However this technique backfired on me since I cannot obtain the algorithms
specific information at destruction time.
The only alternative I see is to call the destruction explicitly before
destruction time... but then RAII is pointless in this case.
The code that currently calls the virtual method has simply been placed
in the wrong destructor. Moving the cleanup call to the destructor of
the derived class that needs to be cleaned up - would produce the
desired result by calling the right clean-up method at the right time.

Greg

Nov 19 '06 #6

Henrik Goldman äæÔÊå ÇÓÊ:
More precisely, when the object is destroyed, B's destructor is called
first. After that finished, the object is not a B anymore. It's only anA
now. Since you don't have an implementation for f1() in A, you get into
trouble when trying to call it.

Correct. It took me a little while to realise this but yes it's right.
E.g. I have a class specific cleanup method which is implemented with a
GoF template pattern.
Why?

My intention is to create a class which uses RAII idiom. Upon destructionit
may need a algorithm specific way for destruction.

It's a class for handled spawning and closed processes. It is platform
independent and support several platforms. However on some unix platformsI
get weird results from fork/child and when I need to shut things down
politely I am sometimes closing the wrong pid. It's a platform specific
problem. However I have an application specific method which is 100%
fool-proof by getting the pid from a special pid file. Therefore I wanted
to create an inherited class to deal with my application specific algorithm.
However this technique backfired on me since I cannot obtain the algorithms
specific information at destruction time.
The only alternative I see is to call the destruction explicitly before
destruction time... but then RAII is pointless in this case.

-- Henrik
how about a pure virtual destructor overridden in a subclass?

Nov 19 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Chunhui Han | last post by:
Hi, I was recently reading about virtual base classes in C++. The book I was reading says that it is illegal to have non-virtual destructor for the virtual base class. It seems to me that...
6
by: BigMan | last post by:
Is it safe to call nonvirtual member functions from ctors and dtors? What about virtual ones?
23
by: heted7 | last post by:
Hi, Most of the books on C++ say something like this: "A virtual destructor should be defined if the class contains at least one virtual member function." My question is: why is it only for...
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
37
by: WittyGuy | last post by:
Hi, I wonder the necessity of constructor and destructor in a Abstract Class? Is it really needed? ? Wg http://www.gotw.ca/resources/clcm.htm for info about ]
3
by: marcwentink | last post by:
Say I have a class A, and a class B that inherits from A. Now A (and B) has a virtual destructor and a virtual function F(); If I now make these statements A* ptrA = new B; ptrA->F(); delete...
3
by: Pravesh | last post by:
Hello All, I had some query regarding virtual functions/destructors. If a class is having some/all of its methods that are virtual then is it recommended that it should also have virtual...
5
by: druberego | last post by:
I read google and tried to find the solution myself. YES I do know that you can get undefined references if you: a) forget to implement the code for a prototype/header file item, or b) you forget...
9
by: desktop | last post by:
On this page: http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html Shape specify the virtual function: virtual double Intersect( const Shape& s) = 0; then the derived class Circle...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.