Archived

This topic is now archived and is closed to further replies.

C++ Destructor problem

This topic is 6611 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Howdy I'm running into a bit of trouble with C++ destructors. This is probably a fairly simple thing... but it's irritating me and I've never noticed the problem before. I have two classes, A and B. Each has a constructor and destructor defined. B is inherited from A. I have a pointer to A in my program which is assigned to point to an object of type B. This calls the constructor of B which calls the constructor of A, executes itself, and returns. However, when I destroy the object, because the pointer is of type A, only the destructor of A is run, and not the destructor of B. If I make the pointer of type B, it works fine. I have included a little code snippet so you can see what I am talking about (assume classes A and B are defined):
  A *aptr = new B(); delete aptr; // this line does not call B's destructor, only A's // however... B *bptr = new B(); delete bptr; // this line calls B's destructor then A's 
I'm sure this is something simple, maybe even correct C++, but I'm not 100% on the C++ standard so any advice would be appreciated on how I can make the code call B's destructor. I'm using MSVC 5. Thanks! Starfall Edited by - Starfall on 7/13/00 2:50:56 PM

Share on other sites
define A''s destructor as
virtual ~A();

i haven''t tried that with destructors, but i had the similar problem with a method inside my classes and i was told to define it as virtual in the base class, so i did and it worked perfectly. i think it''s the same thing for the destructor too

- Pouya / FOO!!!

#define PURE_STUPIDITY 128 PROGRAMMERS

Share on other sites
Aha! So obvious I can''t believe I didn''t think of it! I was somehow under the impression that this should automatically occur for destructors. I use virtual all the time for other member functions, but it never occurred to me...

Thanks for the help.

Starfall

Share on other sites
Are you using Visual C++?

I ask, because Visual C++ doesn''t insist on destructors being virtual, whereas I (and others) are certain that the C++ spec requires that a destructor be virtual, whether or not you declare it such.

I''m interested to know if other C++ compilers, such as GCC/DJGPP, Borland, etc, do this.

Anyway, the bottom line is, /always/ declare your destructors to be virtual - not just the base class. Why?

Well, imagine this:

CObject{  virtual ~CObject();};CBaseWindow : public CObject{  ~CBaseWindow();};CButton : public CBaseWindow{  ~CButton();}CObject *pButton = new CButton();delete pButton;

Can you tell me what would happen? It''s undefined behaviour - I would expect that the CBaseWindow and CObject destructors would get called properly, but not the CButton one, because there''s no polymorphism chain explicitly declared.

This might not be what the C++ spec says, but since when do Microsoft and other obey a spec to the letter?

I think it''s despicable that Visual C++ doesn''t even generate a warning about non-virtual destructors, and that''s at ''warning level 4'' (for those that don''t know, that tells the compiler to be picky as hell).

Personally, I want my compiler to spew errors if it finds a non-virtual destructor, /or/ have an option to give a warning and then treat it as virtual anyway.

Can anyone give a good reason why it should be possible to break the polymorphism chain on destructors?

TheTwistedOne
http://www.angrycake.com

Share on other sites
Speed. Virtual gives you dynamic binding -> added overhead. You violate the principles of c++ if you demand that.

Share on other sites
Besides speed, there are two other reasons not to make destructors virtual.
1) Size. Adding a single virtual method to a class requires the addition of a pointer to the vtable for each instance of the class. This is usually only 4 bytes, but it would double the size of a small class like this:
class point {    unsigned short x, y;};

2) Adding a vtable pointer to a class makes it incompatable with the corresponding struct in C. If you need to pass struct data between libraries in C and C++, you have to make sure that there are no virtual methods (including destructors) on the structs.

However, I agree that the vast majority of time you DO want destructors to be virtual. It would be nice if VC flagged non-virtual destructors as errors, so long as there was a way to #pragma the error off for cases when you KNOW you want non-virtual destructors.

Share on other sites
Borland and Metrowerks compilers do not require virtual dtors

Such a requirement, as said before is, in fact, a violation of the C++ spec.

A dtor is virtual if declared as such or, if it inherits from a base class which has a destructor declared as virtual ( just like methods )

If you do not explicitly declare a dtor the compiler generates one for you - if your class inherits from a class with a virtual dtor then the compiler will generate a virtual dtor, otherwise it will create a non-virtual one.

Personally, I like to make sure and declare things virtual in every class in the heirarchy that they need to be. It makes things clearer when looking at one module. For example:

Module A -

class Base
{
public:

Base();
virtual ~Base();

virtual void Nothing() = 0;
};

Module B - ( a separate .cpp file )

- include Module A -

class Derived : public Base
{
private:

long iVal;

public:

Derived();
virtual ~Derived();

virtual void Nothing();
};

However, declaring all methods virtual can be overkill. Especially since virtual causes inline functions to be out-of-line when the compiler cannot determine the type at compilation time.

Edited by - SteveC on July 14, 2000 5:53:51 PM

Edited by - SteveC on July 14, 2000 5:55:13 PM

Share on other sites
Armitage: Speed. Hmm. Personally, I''d take predictability over performance in the case of destructors.

Syzygy: Oh. I tend to forget that a struct is a class according to C++. That''s a good reason.

SteveC: I quite agree. Regardless of what a compiler does or doesn''t do, it''s always best to write things out fully, for everybody''s sake.

I''m aware of default constructors and destructors - which is why you''d find a lot of empty ones in my classes, if you were to peek at them.

I''m not talking about functions in general, though. I fully understand that making everything virtual is a road to performance hell.

Overall, I suppose that it''s unfair to demand that the default be that destructors are virtual. The biggest argument against, I think, would be that such is the opposite of the normal behaviour.

I don''t think I''m being unreasonable in desiring compilers to tell you if you forget to make a destructor virtual, though. Even as a turned-off-by-default option.

Are you listening, Bill

TheTwistedOne
http://www.angrycake.com

Share on other sites
Well, I misread the question somewhat. I didn't realize that he meant "breaking" a virtual chain. I thought he wanted a reason for omitting a virtual dtor from the beginning (gave my reply in regard to the first post). If you're building a concrete class you shouldn't use virtual, imo, and I honestly don't know what happens if you start making them virtual further down the tree?

But if there is a virtual one at the top, I'd like to find out from the compiler before introducing small...features into my programs

Edited by - Armitage on July 15, 2000 6:07:38 AM

Edited by - Armitage on July 15, 2000 6:09:25 AM

1. 1
2. 2
JoeJ
20
3. 3
frob
16
4. 4
5. 5

• 10
• 10
• 11
• 13
• 9
• Forum Statistics

• Total Topics
632195
• Total Posts
3004717

×