question about default destructors...

A

Avalon1178

Hello,

Are default destructors virtual?

In other words, say I have "class A" and "class B : public A", and I
have the code below:

A * a = new A;
B * b = new B;
a = b;
delete a;

Neither A or B have destructors defined (thus creating a default
destructor for each), when "delete a" is called, will it call b's
destructor first then a's destructor, or will it just call a's
destructor?
 
C

Clem.Dickey

Hello,

Are default destructors virtual?

No, they are not. The rationale is that you should not have to pay for
features you don't use, and sone classes do not need virtual
destructors.
 
R

Robbie Hatley

Avalon1178 said:
Are default destructors virtual?

Nope. Just last night, my compiler (gcc) warned me:
"Warning: class has virtual functions but non-virtual
destructor".

You really only need a virtual destructor if your base class
has virtual functions, and if your derived classes have data
members that need to be destructed differently than than the
base class.
In other words, say I have "class A" and "class B : public A",
and I have the code below:

A * a = new A;
B * b = new B;
a = b;
delete a;

Neither A or B have destructors defined (thus creating a default
destructor for each), when "delete a" is called, will it call b's
destructor first then a's destructor, or will it just call a's
destructor?

That will call A's destructor. If B has dynamically-allocated
data members which A doesn't, that will create a memory leak.
In a case like that, you should put this line in A:

class A
{
public:
A();
virtual ~A();
...
private:
...
};

Then make B's destructor do whatever it needs to do. (Such
as calling "delete" for new'd data members.)

class B : public A
{
public:
B() {Blat = new double;}
~B() {delete Blat;}
...
private:
double *Blat;
...
};

Then if you do this in main():

int main (void)
{
A* Fred = new B;
delete Fred; // calls ~B(), not ~A()
return 42;
}

Fred will then get correctly destructed.
 
G

Ge Chunyuan

Hello,

Are default destructors virtual?

In other words, say I have "class A" and "class B : public A", and I
have the code below:

A * a = new A;
B * b = new B;
a = b;
delete a;

Neither A or B have destructors defined (thus creating a default
destructor for each), when "delete a" is called, will it call b's
destructor first then a's destructor, or will it just call a's
destructor?


No, compiler won't generate default virtual desctrutor.
Once you delete a, it will just invoke A's destructor of course.
You can debug this sample code in the IDE and check whether there is
vptr.
 
T

terminator

Hello,

Are default destructors virtual?

In other words, say I have "class A" and "class B : public A", and I
have the code below:

A * a = new A;
B * b = new B;
a = b;
delete a;

Neither A or B have destructors defined (thus creating a default
destructor for each), when "delete a" is called, will it call b's
destructor first then a's destructor, or will it just call a's
destructor?

it calls A .but from the point at which you define a virtual
destructor ,subsequent derived classes will have virtual versions of
dtor eventhough you do not declare any:

struct A{};
struct B:A{virtual ~B(){};};
struct C:B{};
struct D:C{~D{};};

A* a = new B;
delete a;//call A`s dtor .dtor is not virtual yet

B* b = new c;
delete b;//call C`s dtor. after B dtor will be virtual

delete (b = new D);//call D`s dtor

C* c = new D;
delete c;//call D`s dtor

regards,
FM
 
J

James Kanze

Nope. Just last night, my compiler (gcc) warned me:
"Warning: class has virtual functions but non-virtual
destructor".
You really only need a virtual destructor if your base class
has virtual functions, and if your derived classes have data
members that need to be destructed differently than than the
base class.

I don't know where you got that from, but it is completely
false. If you delete an object of a derived type through a
pointer to the base type, the destructor must be virtual in the
base type. It certainly has nothing to do with what is or is
not present in the derived class---if the dynamic type is
different from the static type, either the destructor in the
static type is virtual, or you have undefined behavior.

Typically, of course, if a class doesn't have virtual functions,
there's no point in deriving from it, or at least, there's no
point in having a pointer to it when the actual object has a
derived type. So typically, if you don't have virtual
functions, you don't need a virtual destructor. Typically;
there are a few rare cases where you might use some sort of
labeling interface, which has no functions of its own.
That will call A's destructor.

Maybe. I might also crash the system. Or reformat your hard
drive. It's undefined behavior.
 
R

Ron Natalie

Avalon1178 said:
Hello,

Are default destructors virtual?
No.


Neither A or B have destructors defined (thus creating a default
destructor for each), when "delete a" is called, will it call b's
destructor first then a's destructor, or will it just call a's
destructor?

It's worse than the destructors not being called right. It's
outright undefined behavior. The language specifically requires
a virtual destructor to delete derived objects through that type.
The implementation is free to key all sorts of stuff (like the
deallocation function) off the presence of the virtual destructor.
 
A

Andrew Koenig

You really only need a virtual destructor if your base class
has virtual functions, and if your derived classes have data
members that need to be destructed differently than than the
base class.

Not true. You need a virtual destructor in your base class whenever you use
a pointer to base to delete a derived-class object. Just because your
implementation happens not to enforce the rule doesn't make the rule go
away.
 
A

Andrew Koenig

IIRC, ~A() will still be called after the B object is destructed.

If class A does not have a virtual destructor, the effect of this example is
undefined, which means that anything could happen.
 
O

Old Wolf

struct A{};
struct B:A{virtual ~B(){};};
struct C:B{};
struct D:C{~D{};};

A* a = new B;
delete a;//call A`s dtor .dtor is not virtual yet

No, this causes undefined behaviour. (As has been
pointed out several times on this thread already
but I thought I'd mention it again in case anyone
was under the impression that this example is
different to the other examples presented).
B* b = new c;

I guess you mean C rather than c.
delete b;//call C`s dtor.

Calls C's dtor and then B's dtor, to be precise.
delete (b = new D);//call D`s dtor

Is that legal? i.e. delete (X=Y)
First impression is that it might fall foul of
sequence point rules and/or the rule about
accessing the result of an assignment.
 
J

James Kanze

Is that legal? i.e. delete (X=Y)
First impression is that it might fall foul of
sequence point rules and/or the rule about
accessing the result of an assignment.

Good question. I think it is, because delete resolves to a
function call (or two, if there is a destructor), and a function
call implies a sequence point; if b is a global variable, and
the destructor of D reads it, it must see the effect of the
assignment, and if the global operator delete has been replaced,
it must also see the effect of the assignment.

On the other hand, it doesn't look too useful, and I don't think
I'd recommend it in production code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top