C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Question about virtual destructors

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Gustavo Guerra
Guest





PostPosted: Wed Sep 29, 2004 5:47 pm    Post subject: Question about virtual destructors Reply with quote



Hello
I need a little help here

Will the following work correctly?

class XPTO
{
public:
int i;
xpto_ptr<int*> iptr;
};

class XPTI: public XPTO
{
public:
double d;
xpto_ptr<double*> dptr;
};

int main()
{
XPTO* ptr = new XPTI();
delete ptr;
}

being xpto_ptr something like scoped_ptr, auto_ptr, move_ptr and variations

Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

I'm in doubt because I don't directly allocate heap data in any class of the
hierarchy.

Regards
Gustavo Guerra



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Ulrich Eckhardt
Guest





PostPosted: Fri Oct 01, 2004 11:39 am    Post subject: Re: Question about virtual destructors Reply with quote



Gustavo Guerra wrote:
Quote:
Will the following work correctly?

class XPTO
{
public:
int i;
xpto_ptr<int*> iptr;
};

class XPTI: public XPTO
{
public:
double d;
xpto_ptr<double*> dptr;
};

int main()
{
XPTO* ptr = new XPTI();

Allocate an XPTI and store it in a pointer to the baseclass. OK.

Quote:
delete ptr;

This uses ptr's type(XPTO) to determine which dtor to call. XPTO's dtor is
not virtual though, which is why only XPTO's dtor gets called. This is not
OK.
If it had been virtual, the call would have been delegated to the dtor of
the most derived class, which would have been right.

Quote:
being xpto_ptr something like scoped_ptr, auto_ptr, move_ptr and
variations

The above won't work, regardless of the smart pointer you use.

Quote:
Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

Yes. If you want to polymorphically delete an object, you need a virtual
dtor.

Speaking of smart pointers, this will work correctly:
boost::shared_ptr<XPTO> ptr = boost::shared_ptr<XPTI>(new XPTI);

When ptr goes out of scope, it will correctly call XPTI's dtor. Event if the
object finally ends in a shared_ptr<void> it will work correctly, if the
first owner was correct.
This is specific to boost::shared_ptr<>, std::auto_ptr<> won't do it, I
don't know about the move_ptr<> you quoted.

Another thing to consider is making the base classes dtor protected. That
way, you can't call the wrong dtor and your program will fail at compile
time.

Uli

--
FAQ: http://parashift.com/c++-faq-lite/
/* bittersweet C++ */
default: break;

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Victor Bazarov
Guest





PostPosted: Fri Oct 01, 2004 11:44 am    Post subject: Re: Question about virtual destructors Reply with quote



"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote...
Quote:
Hello
I need a little help here

Will the following work correctly?

class XPTO
{
public:
int i;
xpto_ptr<int*> iptr;
};

class XPTI: public XPTO
{
public:
double d;
xpto_ptr<double*> dptr;
};

int main()
{
XPTO* ptr = new XPTI();
delete ptr;
}

being xpto_ptr something like scoped_ptr, auto_ptr, move_ptr and
variations

Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

The latter. Any time you delete an object of a derived class through
a pointer to a base class, the destructor has to be virtual or the
behaviour is undefined.

Quote:

I'm in doubt because I don't directly allocate heap data in any class of
the
hierarchy.

It does not matter.

V


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Zian Smith
Guest





PostPosted: Fri Oct 01, 2004 11:48 am    Post subject: Re: Question about virtual destructors Reply with quote

"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote

Quote:
Hello
I need a little help here

Will the following work correctly?

class XPTO
{
public:
int i;
xpto_ptr<int*> iptr;
};

class XPTI: public XPTO
{
public:
double d;
xpto_ptr<double*> dptr;
};

int main()
{
XPTO* ptr = new XPTI();
delete ptr;
}

well since you essentially have a base class pointer that points to a
derived class object, you should have a virtual destructor in your
base class so that the derived class destructor is called when you
delete ptr. The destructors are probably where you want to delete iptr
and dptr.

Quote:

being xpto_ptr something like scoped_ptr, auto_ptr, move_ptr and variations

Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

I'm in doubt because I don't directly allocate heap data in any class of the
hierarchy.

From what I can understand from your code, iptr and dptr will probably
point to data on the heap when you allocate memory for them somewhere
in your code, and you should delete them in the class destructors..


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Bob Hairgrove
Guest





PostPosted: Fri Oct 01, 2004 11:54 am    Post subject: Re: Question about virtual destructors Reply with quote

On 29 Sep 2004 13:47:23 -0400, "Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote:

[snip...]
Quote:
Or will I have to redefine XPTO as

class XPTO
{
public:
int i;
virtual ~XPTO() {}
};

to have correct behavior?
[snip]



Yes.

--
Bob Hairgrove
[email]NoSpamPlease (AT) Home (DOT) com[/email]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
news
Guest





PostPosted: Fri Oct 01, 2004 11:57 am    Post subject: Re: Question about virtual destructors Reply with quote


"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote

Quote:
XPTO* ptr = new XPTI();
delete ptr;

No. You are deleting via a pointer to a base class. XPTO must have virtual destructor.

Quote:
I'm in doubt because I don't directly allocate heap data in any class of the
hierarchy.

What does the above have to do with it? It doesn't have anything to do with the
heap data the class allocates. It has to do with your call to new and delete. You
need the virtual destructor even if XPTO and XPTI didn't have any data members.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Alberto Barbati
Guest





PostPosted: Fri Oct 01, 2004 4:57 pm    Post subject: Re: Question about virtual destructors Reply with quote

Gustavo Guerra wrote:
Quote:
Hello
I need a little help here

Will the following work correctly?

[code omitted]


No.

Quote:
Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

Yes. (but what happened to the xpto_ptr<int*> member?)

Alberto

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Gustavo Guerra
Guest





PostPosted: Fri Oct 01, 2004 5:56 pm    Post subject: Re: Question about virtual destructors Reply with quote

"news" <news (AT) news (DOT) newshosting.com> wrote

Quote:

"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote in message
news:2ruag9F1f15q0U1 (AT) uni-berlin (DOT) de...
XPTO* ptr = new XPTI();
delete ptr;

No. You are deleting via a pointer to a base class. XPTO must have
virtual destructor.

I'm in doubt because I don't directly allocate heap data in any class of
the
hierarchy.

What does the above have to do with it? It doesn't have anything to do
with the
heap data the class allocates. It has to do with your call to new and
delete. You
need the virtual destructor even if XPTO and XPTI didn't have any data
members.


My question is solely based on the fact that I don't need any destructor at
all, so there's no issue of calling the wrong destructor. I'm uncertain is
if the delete operation frees the correct amount of memory. For example,
free in C, on wich delete is bases, doesn't need to know the type, it can
even be a void *, as the standard heap allocator as information regarding
the ammount of memory it allocated starting at that address.

Regards
Gustavo Guerra


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Zian Smith
Guest





PostPosted: Sat Oct 02, 2004 2:20 pm    Post subject: Re: Question about virtual destructors Reply with quote

"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote

Quote:
Hello
I need a little help here

Will the following work correctly?

class XPTO
{
public:
int i;
xpto_ptr<int*> iptr;
};

class XPTI: public XPTO
{
public:
double d;
xpto_ptr<double*> dptr;
};

int main()
{
XPTO* ptr = new XPTI();
delete ptr;
}

well since you essentially have a base class pointer that points to a
derived class object, you should have a virtual destructor in your
base class so that the derived class destructor is called when you
delete ptr. The destructors are probably where you want to delete iptr
and dptr.

Quote:

being xpto_ptr something like scoped_ptr, auto_ptr, move_ptr and variations

Or will I have to redefine XPTO as

class XPTO
{
public:
int i;

virtual ~XPTO() {}
};

to have correct behavior?

I'm in doubt because I don't directly allocate heap data in any class of the
hierarchy.

From what I can understand from your code, iptr and dptr will probably
point to data on the heap when you allocate memory for them somewhere
in your code, and you should delete them in the class destructors..


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Frank Birbacher
Guest





PostPosted: Sun Oct 03, 2004 3:28 am    Post subject: Re: Question about virtual destructors Reply with quote

Hi!

Gustavo Guerra wrote:
Quote:
My question is solely based on the fact that I don't need any destructor at
all, so there's no issue of calling the wrong destructor.

Just because you didn't explicitly write a dtor, doesn't mean
there won't be any. The compiler automatically generates a
default destructor which will invoke the dtors of all members.

Since now in your example the dtor of the most derived class
(XPTI) is not called, the members of it (e.g. dptr) don't get
destructed. That way they have no chance to free up the memory
they allocated.

Quote:
For example,
free in C, on wich delete is bases,

Nothing guarantees that delete invokes free. They are two
individual functionalities.

Quote:
doesn't need to know the type, it can
even be a void *, as the standard heap allocator as information regarding
the ammount of memory it allocated starting at that address.

Other than delete, free does not call the destructor of its
argument. delete does, thus it needs to know the correct type.

Frank


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Oct 04, 2004 7:23 pm    Post subject: Re: Question about virtual destructors Reply with quote

Frank Birbacher <bloodymir.crap (AT) gmx (DOT) net> wrote

Quote:
Gustavo Guerra wrote:

My question is solely based on the fact that I don't need any
destructor at all, so there's no issue of calling the wrong
destructor.

Just because you didn't explicitly write a dtor, doesn't mean there
won't be any. The compiler automatically generates a default
destructor which will invoke the dtors of all members.

Since now in your example the dtor of the most derived class (XPTI) is
not called, the members of it (e.g. dptr) don't get destructed. That
way they have no chance to free up the memory they allocated.

But the problem has nothing to do with calling the correct destructor or
not. The problem is simply that if the static type of the pointer used
in delete does not correspond to the dynamic type of the actual object,
you have undefined behavior. In many cases, for example, the wrong
address will be passed to the operator delete function. Which could
easily cause a program crash, either immediately, or at some undefined
time in the future.

Quote:
For example, free in C, on wich delete is bases,

Nothing guarantees that delete invokes free. They are two individual
functionalities.

True, but they tend to use the same, or similar algorithms. At any
rate, both the operator delete function and the free function must be
passed the exact address that was returned from the operator new
function or the malloc function. If the dynamic type of the object is
not the same as the static type, and the destructor is not virtual,
there's no way for the compiler to get this information.

Quote:
doesn't need to know the type, it can even be a void *, as the
standard heap allocator as information regarding the ammount of
memory it allocated starting at that address.

Other than delete, free does not call the destructor of its
argument. delete does, thus it needs to know the correct type.

Again, it has nothing to do with destructors per se, although this is
another typical symptom of the undefined behavior. When I write:

Base* pb = new Derived ;

the compiler generates whatever code is necessary to change the physical
address, so pb points to the Base part of Derived, and not to the entire
Derived. When I do

delete pb ;

the compiler needs to reverse this conversion; it can only do so if it
can find out the actual most derived type, and it does this by means of
a virtual destructor.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
news
Guest





PostPosted: Tue Oct 05, 2004 6:18 am    Post subject: Re: Question about virtual destructors Reply with quote


"Gustavo Guerra" <gmcg (AT) acm (DOT) org> wrote

Quote:
My question is solely based on the fact that I don't need any destructor at
all, so there's no issue of calling the wrong destructor

It's not a issue of which destructor gets called. The presence of the virtual
destructor is a signal to the compiler that delete is being used polymorhically.
The wrong destructor being called is only one of the possible outcomes. The
wrong deallocation function may also be called or just about anything else.
It is UNDEFINED BEHAVIOR to do what you are doing.

The rule says you must pass the value to delete that is either the return
value (same type) of a prior new, or that value converted to a base class pointer, and
in the latter case, it must have a virtual destructor.

Also note, that delete[] doesn't have the base class option. You must pass
the same type value as you allocated with new[].


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.