Serving the Quantitative Finance Community

 
User avatar
fradiavalo
Topic Author
Posts: 0
Joined: February 21st, 2006, 1:35 pm

Virtual destructor question

April 11th, 2006, 1:55 am

So, suppose we have a class B deriving from A and A does not have a virtual dtor.If we have code like:A* a = new B;delete a; In this case the dtor for A will be called and B's dtor won't be called and we have a memory leak. So, the point of making dtor in A virtual is to call the dtor in B and then dtor in A? Is that correct? What happens if we have code like:B* b = new B;delete b;Do we still leak memory?Can someone explain to me how an object of derived class is destructed? Is the objects dtor called first and then the base class's dtor?Thanks.
 
User avatar
chaenle
Posts: 0
Joined: April 5th, 2006, 1:25 pm

Virtual destructor question

April 11th, 2006, 7:08 am

> A* a = new B;> delete a; >> In this case the dtor for A will be called and B's dtor won't be called and we have a memory leak. So, the point of making dtor in A > virtual is to call the dtor in B and then dtor in A? Is that correct? That's correct, only A's destructor is called. This need not necessarily be a memory leak though (for example if B's destructor does not release any memory at all). In general, the rule is: Base classes with no virtual destructor are not suited for inheritance.> What happens if we have code like:> B* b = new B;> delete b;First B's destructor is called, then A's, so no problem here, no memory leaks.>Can someone explain to me how an object of derived class is destructed? Is the objects dtor called first and then the base class's >dtor?Correct, the order of destruction is the reverse of the order of object construction. When creating an object of type B, first A's constructor is first called, then B's. When deleting an object, first B's destructor is first called and then A's. If during object creation, A's constructor were throwing an exception, no destructor would be called; if B's constructor were throwing an exception, the exception mechanism would only call A's destructor.
 
User avatar
madmax
Posts: 0
Joined: October 31st, 2003, 9:56 am

Virtual destructor question

April 11th, 2006, 10:43 am

Chaenle is right except for the first question:> A* a = new B;> delete a; >> In this case the dtor for A will be called and B's dtor won't be called and we have a memory leak. So, the point of making dtor in A > virtual is to call the dtor in B and then dtor in A? Is that correct? >>That's correct, only A's destructor is called. This need not necessarily be a memory leak though (for example if B's destructor does not >>release any memory at all). In general, the rule is: Base classes with no virtual destructor are not suited for inheritance.This is not exact, although that is the most likely behavior. According to the standard, when deleting a derived class instance through a base class pointer when the base does not declare a virtual destructor, the BEHAVIOR IS UNDEFINED, that is a compiler implementer can decide whatever he wants.
 
User avatar
chaenle
Posts: 0
Joined: April 5th, 2006, 1:25 pm

Virtual destructor question

April 11th, 2006, 12:39 pm

Declaring A* a = new Band calling a->f() results in a call to A::f if f is non-virtual, even if B overrides f.A destructor is little more than a member function ("operator~()") that also calls its base class(es) member functions. operator~() is called automatically upon delete or when an object goes out of scope prior to freeing the memory used by the object's attributes. So why should f() be defined and operator~() be undefined??Bjarne Stroustrup, the c++ inventor, addresses the problem in his faq ("http://public.research.att.com/~bs/bs_faq2.html", see "Why are destructors not virtual by default") and confirms what I previously wrote. I wonder where in the c++ standard you read about the undefined behavior.
 
User avatar
madmax
Posts: 0
Joined: October 31st, 2003, 9:56 am

Virtual destructor question

April 11th, 2006, 1:41 pm

No, Stroustrup does not say what happens when you do that. He only say you should not do it.From the standard:5.3.5 Delete [expr.delete]1 The delete expressionoperator destroys a most derived object (1.7) or array created by a newexpression.deleteexpression::pt delete castexpression:pt delete [ ] castexpressionThe first alternative is for nonarrayobjects, and the second is for arrays. The operand shall have a pointertype, or a class type having a single conversion function (12.3.2) to a pointer type. The result has typevoid........3 In the first alternative (delete object), if the static type of the operand is different from its dynamic type, thestatic type shall be a base class of the operand’s dynamic type and the static type shall have a virtualdestructor or the behavior is undefined. QuoteA destructor is little more than a member function ("operator~()") that also calls its base class(es) member functions. operator~() is called automatically upon delete or when an object goes out of scope prior to freeing the memory used by the object's attributes. So why should f() be defined and operator~() be undefined??A destructor is different:- names are different when derived (~A() vs ~B() eventhough B derived from A)- destructors should never throw exceptions....
Last edited by madmax on April 10th, 2006, 10:00 pm, edited 1 time in total.
 
User avatar
fradiavalo
Topic Author
Posts: 0
Joined: February 21st, 2006, 1:35 pm

Virtual destructor question

April 12th, 2006, 11:54 am

Thank you guys, your answers helped a lot.