473,406 Members | 2,769 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,406 software developers and data experts.

why virtual base dtor gets called?

Is it correct that the virtual dtor of base gets called implicitly?
Here's some code to demonstrate what I mean:
Class B has a virtual destructor, so has class D which
is derived from B. Deleting D calls the dtor of D and
then the dtor of B.
I was thinking that this would be true only for non-virtual dtor case,
but I wouldn't have expected it happen for a virtual dtor.
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.
What's correct? Is maybe my compiler buggy?

class B
{
public:
B() {}
virtual ~B() { std::cout << "~B\n"; }
};

class D : public B
{
public:
D() {}
virtual ~D() { std::cout << "~D\n"; }
};

void virtual_dtor_tester()
{
B b;
D d;
}

/* output:
~D
~B
~B
*/
Jul 23 '05 #1
27 2092
> For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.


Nope. Since D is a B, the base part of D must be destroyed, hence ~B() is
called.
That is always true regardless of whether B or D contains virtual functions.

Compiler is correct.

Stephen Howe
Jul 23 '05 #2

"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
Is it correct that the virtual dtor of base gets called implicitly?
Not really, the virtual d~tor of base class is invoked, not called.
Here's some code to demonstrate what I mean:
Class B has a virtual destructor, so has class D which
is derived from B. Deleting D calls the dtor of D and
then the dtor of B.
B's d~tor is invoked and processed before D's d~tor can complete.
I was thinking that this would be true only for non-virtual dtor case,
but I wouldn't have expected it happen for a virtual dtor.
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.
You are describing a non-virtual d~tor. Only D's d~tor would be invoke.
Which is the crux of the arguement of why a derived class needs the base to
have the virtual d~tor.
What's correct? Is maybe my compiler buggy?

class B
{
public:
B() {}
virtual ~B() { std::cout << "~B\n"; }
};

class D : public B
{
public:
D() {}
virtual ~D() { std::cout << "~D\n"; }
};

void virtual_dtor_tester()
{
B b;
D d;
}

/* output:
~D
~B
~B
*/


Try:

#include <iostream>

class B
{
public:
B() { std::cout << "B\n"; }
virtual ~B() { std::cout << "~B\n"; }
};

class D : public B
{
public:
D() { std::cout << "D\n"; }
~D() { std::cout << "~D\n"; }
};

class E : public D
{
public:
E() { std::cout << "E\n"; }
~E() { std::cout << "~E\n"; }
};
int main(int argc, char* argv[])
{
E e;

return 0;
}

/*
B
D
E
~E
~D
~B
*/

Note: d~tors ~D() and ~E() are automatically virtual.

Jul 23 '05 #3
Peter Julian wrote:
tuvok wrote:
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.
You are describing a non-virtual d~tor. Only D's d~tor would be
invoke. Which is the crux of the arguement of why a derived class
needs the base to have the virtual d~tor.


Please don't answer questions here if you don't know what
you are talking about. Invoking a derived class's destructor
ALWAYS calls the base class destructors.

The virtualness of the base class destructor only comes into
play when the object is deleted via a pointer to the base
class.
Try:

#include <iostream>

class B
{
public:
B() { std::cout << "B\n"; }
virtual ~B() { std::cout << "~B\n"; }
};

class D : public B
{
public:
D() { std::cout << "D\n"; }
~D() { std::cout << "~D\n"; }
};

class E : public D
{
public:
E() { std::cout << "E\n"; }
~E() { std::cout << "~E\n"; }
};
int main(int argc, char* argv[])
{
E e;

return 0;
}

/*
B
D
E
~E
~D
~B
*/


The output will be the same even if B's dtor is not virtual.
Try it and see.

Jul 23 '05 #4
"Peter Julian" wrote

"tuvok" wrote in message
Is it correct that the virtual dtor of base gets called implicitly?
Not really, the virtual d~tor of base class is invoked, not called.
Here's some code to demonstrate what I mean:
Class B has a virtual destructor, so has class D which
is derived from B. Deleting D calls the dtor of D and
then the dtor of B.


B's d~tor is invoked and processed before D's d~tor can complete.
I was thinking that this would be true only for non-virtual dtor case,
but I wouldn't have expected it happen for a virtual dtor.
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.


You are describing a non-virtual d~tor. Only D's d~tor would be invoke.


No, it's not the case. Both ~D and ~B are invoked no matter whether
the dtors are virtual or not. So there seems no difference whether
the dtors are virtual or not. Ie. always the dtors of all parts get invoked.
Which is the crux of the arguement of why a derived class needs the base to
have the virtual d~tor.

Jul 23 '05 #5
The code below illustrates the difference between the virtual (V) and
non-virtual (NV) cases. The difference occurs when you have a base pointer
to a derived class.
#include <iostream>

class BaseV
{
public:
BaseV() { std::cout << "BaseV\n"; }
virtual ~BaseV() { std::cout << "~BaseV\n"; }
};

class DerivedV : public BaseV
{
public:
DerivedV() { std::cout << "DerivedV\n"; }
~DerivedV() { std::cout << "~DerivedV\n"; }
};

class BaseNV
{
public:
BaseNV() { std::cout << "BaseNV\n"; }
~BaseNV() { std::cout << "~BaseNV\n"; }
};

class DerivedNV : public BaseNV
{
public:
DerivedNV() { std::cout << "DerivedNV\n"; }
~DerivedNV() { std::cout << "~DerivedNV\n"; }
};
int main(int argc, char* argv[])
{
BaseV *ptrV = new DerivedV;
delete ptrV;

BaseNV *ptrNV = new DerivedNV;
delete ptrNV;
}
--
John Carson

Jul 23 '05 #6
"John Carson" wrote
The code below illustrates the difference between the virtual (V) and
non-virtual (NV) cases. The difference occurs when you have a base pointer
to a derived class.
#include <iostream>

class BaseV
{
public:
BaseV() { std::cout << "BaseV\n"; }
virtual ~BaseV() { std::cout << "~BaseV\n"; }
};

class DerivedV : public BaseV
{
public:
DerivedV() { std::cout << "DerivedV\n"; }
~DerivedV() { std::cout << "~DerivedV\n"; }
};

class BaseNV
{
public:
BaseNV() { std::cout << "BaseNV\n"; }
~BaseNV() { std::cout << "~BaseNV\n"; }
};

class DerivedNV : public BaseNV
{
public:
DerivedNV() { std::cout << "DerivedNV\n"; }
~DerivedNV() { std::cout << "~DerivedNV\n"; }
};
int main(int argc, char* argv[])
{
BaseV *ptrV = new DerivedV;
delete ptrV;

BaseNV *ptrNV = new DerivedNV;
delete ptrNV;
}


I see. Thanks.
I've slightly extended it to show the difference also vs. stack objects:

void test_virt_vs_nonvirt_dtor()
{
std::cout << "Derived objects created on stack:\n";
{
std::cout << " Creating:\n";
DerivedV dv;
DerivedNV dnv;
std::cout << " Destroying:\n";
}

std::cout << "\nDerived objects using ptr to base created on heap:\n";
std::cout << " Creating:\n";
BaseV *ptrV = new DerivedV;
BaseNV *ptrNV = new DerivedNV;
std::cout << " Destroying:\n";
delete ptrNV;
delete ptrV;
}

Here's the output:

Derived objects created on stack:
Creating:
BaseV
DerivedV
BaseNV
DerivedNV
Destroying:
~DerivedNV
~BaseNV
~DerivedV
~BaseV

Derived objects using ptr to base created on heap:
Creating:
BaseV
DerivedV
BaseNV
DerivedNV
Destroying:
~BaseNV
~DerivedV
~BaseV

So, bottom line is: using ptr to base does not (can not) call the dtor of derived,
unless the dtor is virtual.
Jul 23 '05 #7
"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com

So, bottom line is: using ptr to base does not (can not) call the
dtor of derived, unless the dtor is virtual.


Yep.

--
John Carson
Jul 23 '05 #8

"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
Peter Julian wrote:
tuvok wrote:
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.


You are describing a non-virtual d~tor. Only D's d~tor would be
invoke. Which is the crux of the arguement of why a derived class
needs the base to have the virtual d~tor.


Please don't answer questions here if you don't know what
you are talking about. Invoking a derived class's destructor
ALWAYS calls the base class destructors.


He said "when D gets deleted". Please don't criticize my comments if you
can't even read the post. Incidentally, the base destructor isn't called,
its invoked. That means that you can't overide the base d~tor, in case you
are wondering what the difference is.

In the case a pointer to D is was involved, B's d~tor would not be invoked.

While my example didn't include a pointer to the derived class, the output
doesn't produce the warning.
Jul 23 '05 #9

"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
"Peter Julian" wrote

"tuvok" wrote in message
Is it correct that the virtual dtor of base gets called implicitly?
Not really, the virtual d~tor of base class is invoked, not called.
Here's some code to demonstrate what I mean:
Class B has a virtual destructor, so has class D which
is derived from B. Deleting D calls the dtor of D and
then the dtor of B.


B's d~tor is invoked and processed before D's d~tor can complete.
I was thinking that this would be true only for non-virtual dtor case,
but I wouldn't have expected it happen for a virtual dtor.
For a class with a virtual dtor I would have expected that only
the dtor of D would be called when D gets deleted.


You are describing a non-virtual d~tor. Only D's d~tor would be invoke.


No, it's not the case. Both ~D and ~B are invoked no matter whether
the dtors are virtual or not. So there seems no difference whether
the dtors are virtual or not. Ie. always the dtors of all parts get

invoked.


In the case where a pointer isn't involved, the base's d~tor will still be
invoked but you'll have the warning. You said "when D gets deleted". In the
case you had a pointer, something i didn't include in my example, your base
c~tor would not have been invoked.

Jul 23 '05 #10

"Peter Julian" <p_******@trap.trap.com> wrote in message
news:Rf*******************@news20.bellglobal.com.. .

"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
"Peter Julian" wrote
>
> "tuvok" wrote in message
>
> > Is it correct that the virtual dtor of base gets called implicitly?
>
> Not really, the virtual d~tor of base class is invoked, not called.
>
> > Here's some code to demonstrate what I mean:
> > Class B has a virtual destructor, so has class D which
> > is derived from B. Deleting D calls the dtor of D and
> > then the dtor of B.
>
> B's d~tor is invoked and processed before D's d~tor can complete.
>
> > I was thinking that this would be true only for non-virtual dtor
> > case,
> > but I wouldn't have expected it happen for a virtual dtor.
> > For a class with a virtual dtor I would have expected that only
> > the dtor of D would be called when D gets deleted.
>
> You are describing a non-virtual d~tor. Only D's d~tor would be invoke.


No, it's not the case. Both ~D and ~B are invoked no matter whether
the dtors are virtual or not. So there seems no difference whether
the dtors are virtual or not. Ie. always the dtors of all parts get

invoked.


In the case where a pointer isn't involved, the base's d~tor will still be
invoked but you'll have the warning. You said "when D gets deleted". In
the
case you had a pointer, something i didn't include in my example, your
base
c~tor would not have been invoked.


Eh? Of course the base class destructor is invoked! Whenever a derived
class is destroyed, the destructors for any base classes *must* be invoked,
whether you're using pointers or automatic variables. Otherwise, the memory
allocated for the base class portion(s) of the object would never get
returned to the system.

This is even true if the derived class object was assigned to a base class
pointer variable. The only difference in that case is that the base class
destructor needs to be virtual, or else the *derived* class destructor will
not get invoked.

There is no way for the destruction of the derived class to *not* also
invoke the destructor of the base class (aside from invoking undefined
behavior or abnormally terminating the process).

-Howard

Jul 23 '05 #11

"Howard" <al*****@hotmail.com> wrote in message
news:ZHire.947605$w62.229941@bgtnsc05-
In the case where a pointer isn't involved, the base's d~tor will still
be
invoked but you'll have the warning. You said "when D gets deleted". In
the
case you had a pointer, something i didn't include in my example, your
base
c~tor would not have been invoked.


"c~tor"???

You *did* mean "destructor" there, didn't you? I saw the ~, and missed the
"c" in front, but you were talking about destructors, so I'm assuming that's
what you meant. If you mean the "constructor", though, my argument is the
same...the base classes' constructor(s) must also be invoked, either
explicitly or implicitly, whenever a derived class it created, regardless of
whether you're using pointers or automatic variables.

-Howard
Jul 23 '05 #12

"Peter Julian" <p_******@trap.trap.com> skrev i en meddelelse
news:B9*******************@news20.bellglobal.com.. .

"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
Peter Julian wrote:
> tuvok wrote:
>> For a class with a virtual dtor I would have expected that only
>> the dtor of D would be called when D gets deleted.
>
> You are describing a non-virtual d~tor. Only D's d~tor would be
> invoke. Which is the crux of the arguement of why a derived class
> needs the base to have the virtual d~tor.
Please don't answer questions here if you don't know what
you are talking about. Invoking a derived class's destructor
ALWAYS calls the base class destructors.


He said "when D gets deleted". Please don't criticize my comments if you
can't even read the post. Incidentally, the base destructor isn't called,
its invoked. That means that you can't overide the base d~tor, in case you
are wondering what the difference is.

In the case a pointer to D is was involved, B's d~tor would not be
invoked.


This is plain rubbish. If D inherits from B, B's destructor will be invoked
when deleting a D-object. And this has nothing to do with whether a
destructor is virtual or not.


/Peter
Jul 23 '05 #13
tuvok wrote:
Is it correct that the virtual dtor of base gets called implicitly?


Yes. Let me reiterate to make sure you understand.

When an object is created, at the level of the most
derived object all the virtual bases are constructed
(in a depth first, left to right fashion). Then the
direct bases of the classes are constructed (in the
order listed in the class definition, not the mem-initializer
list), and then each non-static data member is constructed.
Then the constructor body of the object is run.

Each subobject above recursively constructs it's subobjects
(with the exception of avoiding duplicate construction of
the virtual bases).

There is nothing the program can do to change that ordering
(within defined behavior).
Objects are destructed in precisely the REVERSE ORDERING.

Virtualness of the destructor, arguments to the constructor,
etc... have no bearing on this behavior. It always happens
in the same topological order described above.
Jul 23 '05 #14

"Peter Koch Larsen" <pk*****@mailme.dk> wrote in message
news:It********************@news000.worldonline.dk ...

"Peter Julian" <p_******@trap.trap.com> skrev i en meddelelse
news:B9*******************@news20.bellglobal.com.. .

"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
Peter Julian wrote:
> tuvok wrote:
>> For a class with a virtual dtor I would have expected that only
>> the dtor of D would be called when D gets deleted.
>
> You are describing a non-virtual d~tor. Only D's d~tor would be
> invoke. Which is the crux of the arguement of why a derived class
> needs the base to have the virtual d~tor.

Please don't answer questions here if you don't know what
you are talking about. Invoking a derived class's destructor
ALWAYS calls the base class destructors.
He said "when D gets deleted". Please don't criticize my comments if you
can't even read the post. Incidentally, the base destructor isn't called, its invoked. That means that you can't overide the base d~tor, in case you are wondering what the difference is.

In the case a pointer to D is was involved, B's d~tor would not be
invoked.


This is plain rubbish. If D inherits from B, B's destructor will be

invoked when deleting a D-object. And this has nothing to do with whether a
destructor is virtual or not.


That was a typo or rather a mistake. I meant a base B pointer to D. As in...

int main(int argc, char* argv[])
{
B* p_d = new D;

delete p_d;

return 0;
}

Jul 23 '05 #15

"Howard" <al*****@hotmail.com> wrote in message
news:ZH*********************@bgtnsc05-news.ops.worldnet.att.net...

"Peter Julian" <p_******@trap.trap.com> wrote in message
news:Rf*******************@news20.bellglobal.com.. .

"tuvok" <52***************@t-online.de> wrote in message
news:d8*************@news.t-online.com...
"Peter Julian" wrote
>
> "tuvok" wrote in message
>
> > Is it correct that the virtual dtor of base gets called implicitly?
>
> Not really, the virtual d~tor of base class is invoked, not called.
>
> > Here's some code to demonstrate what I mean:
> > Class B has a virtual destructor, so has class D which
> > is derived from B. Deleting D calls the dtor of D and
> > then the dtor of B.
>
> B's d~tor is invoked and processed before D's d~tor can complete.
>
> > I was thinking that this would be true only for non-virtual dtor
> > case,
> > but I wouldn't have expected it happen for a virtual dtor.
> > For a class with a virtual dtor I would have expected that only
> > the dtor of D would be called when D gets deleted.
>
> You are describing a non-virtual d~tor. Only D's d~tor would be invoke.
No, it's not the case. Both ~D and ~B are invoked no matter whether
the dtors are virtual or not. So there seems no difference whether
the dtors are virtual or not. Ie. always the dtors of all parts get invoked.


In the case where a pointer isn't involved, the base's d~tor will still be invoked but you'll have the warning. You said "when D gets deleted". In
the
case you had a pointer, something i didn't include in my example, your
base
c~tor would not have been invoked.


Eh? Of course the base class destructor is invoked! Whenever a derived
class is destroyed, the destructors for any base classes *must* be

invoked, whether you're using pointers or automatic variables. Otherwise, the memory allocated for the base class portion(s) of the object would never get
returned to the system.

This is even true if the derived class object was assigned to a base class
pointer variable. The only difference in that case is that the base class
destructor needs to be virtual, or else the *derived* class destructor will not get invoked.

There is no way for the destruction of the derived class to *not* also
invoke the destructor of the base class (aside from invoking undefined
behavior or abnormally terminating the process).

-Howard


I meant a Base * to a new D. My mistake. Its been a long day.

Jul 23 '05 #16

"Ron Natalie" <ro*@spamcop.net> wrote in message
news:42***********************@news.newshosting.co m...
tuvok wrote:
Is it correct that the virtual dtor of base gets called implicitly?


Yes. Let me reiterate to make sure you understand.

When an object is created, at the level of the most
derived object all the virtual bases are constructed
(in a depth first, left to right fashion). Then the
direct bases of the classes are constructed (in the
order listed in the class definition, not the mem-initializer
list), and then each non-static data member is constructed.
Then the constructor body of the object is run.

Each subobject above recursively constructs it's subobjects
(with the exception of avoiding duplicate construction of
the virtual bases).

There is nothing the program can do to change that ordering
(within defined behavior).
Objects are destructed in precisely the REVERSE ORDERING.

Virtualness of the destructor, arguments to the constructor,
etc... have no bearing on this behavior. It always happens
in the same topological order described above.


I just wrote a program and compiled and ran to test this theory, and it
seems
that "Objects are destructed in precisely the REVERSE ORDERING" is
not always true. Here is the program:

#include <iostream>

class base
{
public:
int i;
base() { std::cout << "b ctor" << std::endl; }
~base() { std::cout << "b dtor" << std::endl; }
};

class derived : public base
{
public:
derived() { std::cout << "d ctor" << std::endl; }
~derived() { std::cout << "d dtor" << std::endl; }
};

int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;

std::cout << std::endl;

d = new derived;
delete d;

char c;
std::cin >> c;

return 0;

}

And it's Output:

b ctor
d ctor
b dtor

b ctor
d ctor
d dtor
b dtor

As you can see, the derived dtor was NOT called when the derived was
instatized to a base pointer.

Change the base dtor to:

produces this output:
b ctor
d ctor
d dtor
b dtor

b ctor
d ctor
d dtor
b dtor

Where the derived dtor is called in both instances.

But, yes, the base dtor does get called in either case either.
Jul 23 '05 #17
"Jim Langston" <ta*******@rocketmail.com> wrote in message
news:4%***************@fe07.lga...

Where the derived dtor is called in both instances.
virtual ~base() { std::cout << "b dtor" << std::endl; }
But, yes, the base dtor does get called in either case either.


(Sorry, left out that one line)
Jul 23 '05 #18
Jim Langston wrote:
Each subobject above recursively constructs it's subobjects
(with the exception of avoiding duplicate construction of
the virtual bases).

There is nothing the program can do to change that ordering
(within defined behavior).
Objects are destructed in precisely the REVERSE ORDERING.

I just wrote a program and compiled and ran to test this theory, and it
seems
that "Objects are destructed in precisely the REVERSE ORDERING" is
not always true. Here is the program:

I was referring to the order of destruction of subobjects in
an object.
Jul 23 '05 #19
Jim Langston wrote:

int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;

This is UNDEFINED BEHAVIOR... your program is incorrect
and there is no point in even conjecture as to what
the observable behavior is.

It has no bearing on the original problem or my answer.
Jul 23 '05 #20

"Ron Natalie" <ro*@spamcop.net> wrote in message
news:42**************@spamcop.net...
Jim Langston wrote:

int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;

This is UNDEFINED BEHAVIOR... your program is incorrect
and there is no point in even conjecture as to what
the observable behavior is.

It has no bearing on the original problem or my answer.


What part of it is undefined behavior? AFAIK everything I did in my
program follows ANSI C and the behavior that resulted. If I'm doing
something undefined I wanna know what it is so I won't do it anymore.
Jul 23 '05 #21
Jim Langston <ta*******@rocketmail.com> wrote:
|
| "Ron Natalie" <ro*@spamcop.net> wrote in message
| news:42**************@spamcop.net...
| > Jim Langston wrote:
| >
| >>
| >> int _tmain(int argc, _TCHAR* argv[])
| >> {
| >> base* b;
| >> derived* d;
| >>
| >> b = new derived;
| >> delete b;
| >>
| > This is UNDEFINED BEHAVIOR... your program is incorrect
| > and there is no point in even conjecture as to what
| > the observable behavior is.
| >
| > It has no bearing on the original problem or my answer.
|
| What part of it is undefined behavior? AFAIK everything I did in my
| program follows ANSI C and the behavior that resulted. If I'm doing
| something undefined I wanna know what it is so I won't do it anymore.

From § 5.3.5.3 (about delete expressions):
if the static type of the operand is different from its dynamic type,
the static type shall be a base class of the operands dynamic type
and the static type shall have a virtual destructor or the behavior
is undefined.

Since the static type of *b is base, and the dynamic is derived, base
ought to have a virtual destructor. Btw: This is from the C++ standard,
not C.
--
Robert Bauck Hamar
Jul 23 '05 #22
Jim Langston wrote:
"Ron Natalie" <ro*@spamcop.net> wrote in message
news:42**************@spamcop.net...
Jim Langston wrote:

int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;


This is UNDEFINED BEHAVIOR... your program is incorrect
and there is no point in even conjecture as to what
the observable behavior is.

It has no bearing on the original problem or my answer.

What part of it is undefined behavior? AFAIK everything I did in my
program follows ANSI C and the behavior that resulted. If I'm doing
something undefined I wanna know what it is so I won't do it anymore.

Deleting a derived object through a pointer to a base class is undefined
behavior when the base class doesn't have a virtual destructor.
Jul 23 '05 #23
On 2005-06-15 18:15:30 -0400, "Jim Langston" <ta*******@rocketmail.com> said:

"Ron Natalie" <ro*@spamcop.net> wrote in message
news:42**************@spamcop.net...
Jim Langston wrote:

int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;
This is UNDEFINED BEHAVIOR... your program is incorrect
and there is no point in even conjecture as to what
the observable behavior is.

It has no bearing on the original problem or my answer.


What part of it is undefined behavior?

I notice two things:

1) The name "_tmain", if in the global namespace, is reserved for implementors.
2) If base does not have a virtual destructor, then "delete b" is UB.

AFAIK everything I did in my program follows ANSI C and the behavior that resulted.
I hope that you meant ANSI C++ there :)

If I'm doing something undefined I wanna know what it is so I won't
do it anymore.

--
Clark S. Cox, III
cl*******@gmail.com

Jul 23 '05 #24
> That was a typo or rather a mistake. I meant a base B pointer to D. As
in...

int main(int argc, char* argv[])
{
B* p_d = new D;

delete p_d;

return 0;
}


Following your arguments: you are wrong.
You said, "You are describing a non-virtual d~tor. Only D's d~tor would be
invoke."

You know what the standard says ?
It says that it is UNDEFINED.
That means you cannot conclude "Only D's d~tor would be invoke." if B lacks
a virtual destructor and you have the above code.
Anything is legitimate.
It may well be that on your implementation that only D's dtor is invoked but
that is just _THAT_ implementation.

SH
Jul 23 '05 #25
> ..., or else the *derived* class destructor will not get invoked.

"Or else" nothing. It is undefined behaviour according to C++ standard.
Nothing can be concluded as to how it behaves.

SH
Jul 23 '05 #26

"Clark S. Cox III" <cl*******@gmail.com> wrote in message
news:2005061519100450073%clarkcox3@gmailcom...
On 2005-06-15 18:15:30 -0400, "Jim Langston" <ta*******@rocketmail.com>
said:

"Ron Natalie" <ro*@spamcop.net> wrote in message
news:42**************@spamcop.net...
Jim Langston wrote:
int _tmain(int argc, _TCHAR* argv[])
{
base* b;
derived* d;

b = new derived;
delete b;

This is UNDEFINED BEHAVIOR... your program is incorrect
and there is no point in even conjecture as to what
the observable behavior is.

It has no bearing on the original problem or my answer.
What part of it is undefined behavior?

I notice two things:

1) The name "_tmain", if in the global namespace, is reserved for
implementors.


Ahh, well, I simply let M$ VC++ .net 2003 create a console program for me
and
threw in the code, cimpiled and ran. I didnt' think to check how it mangled
main. My bad.
2) If base does not have a virtual destructor, then "delete b" is UB.
So, then, if I *always* give a base class that is going to have derived
classes a virtual
destructor then I"ll be in ANSI compliance and DB. Good to know. I"ll try
to make sure
I use virtual dtors on base classes.
AFAIK everything I did in my
program follows ANSI C and the behavior that resulted.

I hope that you meant ANSI C++ there :)


Yeah, I did. Type there.

Thanks for the info.
Jul 23 '05 #27

"Stephen Howe" <sjhoweATdialDOTpipexDOTcom> wrote in message
news:42*********************@news.dial.pipex.com.. .
..., or else the *derived* class destructor will not get invoked.


"Or else" nothing. It is undefined behaviour according to C++ standard.
Nothing can be concluded as to how it behaves.

SH


Sorry, you're correct. It's undefined behavior.
-Howard
Jul 23 '05 #28

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

Similar topics

20
by: qazmlp | last post by:
My class in a header file, contains inline virtual destructor. Is this Ok? Can it cause any problems? class base { public: base() { } virtual ~base { std::cout<<"Inside virtual destructor\n";...
2
by: grahamo | last post by:
Hi, I recently did a test which required the user to note that a base class had a non virtual destructor. Hence the dtor wouldn't be called when the object was deleted. The code is below...
7
by: Oleksii | last post by:
Hello, I'm rather new to the advanced topics, therefore I cannot explain the following myself. Could anyone give me a hint on this one? I'm trying to avoid link-time dependencies on (a test...
8
by: daniel | last post by:
I wonder if there is any reasonable reason to make virtual destructor protected within a derived class purposely?
6
by: Gerhard Prilmeier | last post by:
Hello, I have an unmanaged C++ API that uses virtual functions, like this: class A { public: virtual void handleMe(){} };
23
by: Dave Rahardja | last post by:
Since C++ is missing the "interface" concept present in Java, I've been using the following pattern to simulate its behavior: class Interface0 { public: virtual void fn0() = 0; };
2
by: Mahesh | last post by:
Hi, I encounted some problems using GDB with classes that use virtual inheritance. To illustrate this issue, I have created a simple test case. Here it goes. #include <iostream>
12
by: subramanian100in | last post by:
Suppose class Base { public: virtual ~Test() { ... } // ... }; class Derived : public Base
23
by: Chris Gordon-Smith | last post by:
Hello All I have a base class called Action_Request, and a set of classes corresponding to different kinds of Action_Request, each of which inherits from Action_Request. Eg:- class ...
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
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.