Board index » delphi » destructors

destructors

I built a custom class with a memory built into it.

to free the memory stream when I free the object, should I modify the Free
or Destroy method of the parent class?

I want to Free the inherited class with the free method, but I am interested
in the conventionally accepted style.

thanks,
JJ

 

Re:destructors


Quote
On Fri, 3 Mar 2000 11:50:48 -0500, "JJ" <g...@dfg.com> wrote in message

<v5Sv4.380$sY2.752@client>:

Quote
>I built a custom class with a memory built into it.

>to free the memory stream when I free the object, should I modify the Free
>or Destroy method of the parent class?

>I want to Free the inherited class with the free method, but I am interested
>in the conventionally accepted style.

Change the Destroy method.  It's virtual.  The Free method is static;
it checks that Self is valid, then calls Destroy.

This lets you call Free on a nil pointer; calling Destroy on a nil
pointer would die.

Duncan Murdoch

Re:destructors


Hi!

Quote
> to free the memory stream when I free the object, should I modify
the Free
> or Destroy method of the parent class?

> I want to Free the inherited class with the free method, but I am
interested
> in the conventionally accepted style.

You should always override the Destroy procedure, because this is the
official destructor where the object is killed. (don't forget to call
the inherited destructor at the end).

cu Quarc

Re:destructors


    It's not just style - there's one right way to do this. You need to
override the Destroy method.

    That's _override_, not just "modify" or "change":

type
    TNewClass
        destructor Destroy; override;
    end;

If you leave out the "override" things won't work right.

    Then when you want to free one of your objects you
should call the Free method.

Quote
JJ wrote:
> I built a custom class with a memory built into it.

> to free the memory stream when I free the object, should I modify the Free
> or Destroy method of the parent class?

> I want to Free the inherited class with the free method, but I am interested
> in the conventionally accepted style.

> thanks,
> JJ

Re:destructors


To elaborate:

(1) You must override constructors and destructors.  
(2) You must call inherited constructors first; inherited destructors
last.
(3) I recommend very strongly that you should set all pointers to NIL
immediately after you free it.  And I don't give a <!> if Delphi
suggests to you that you don't need it.  I once lost $10,000 in hard
money to a double-free error caused by a garbage pointer in a
destructor.
(4) Test, with the de{*word*81}, to be certain that all of the constructor
and destructor code actually is being called as you expect it will.

Quote
David C. Ullrich wrote:

>     It's not just style - there's one right way to do this. You need to
> override the Destroy method.

>     That's _override_, not just "modify" or "change":

> type
>     TNewClass
>         destructor Destroy; override;
>     end;

> If you leave out the "override" things won't work right.

>     Then when you want to free one of your objects you
> should call the Free method.

> JJ wrote:

> > I built a custom class with a memory built into it.

> > to free the memory stream when I free the object, should I modify the Free
> > or Destroy method of the parent class?

> > I want to Free the inherited class with the free method, but I am interested
> > in the conventionally accepted style.

> > thanks,
> > JJ

--
------------------------------------------------------------------
Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259
mailto:i...@sundialservices.com  (PGP public key available.)

- Show quoted text -

Quote
> Fast(!), automatic table-repair with two clicks of the mouse!
> ChimneySweep(R):  "Click click, it's fixed!" {tm}
> http://www.sundialservices.com/products/chimneysweep

Re:destructors


Quote
On Sat, 04 Mar 2000 17:14:10 -0700, Sundial Services wrote:
>To elaborate:

>(1) You must override constructors and destructors.  
>(2) You must call inherited constructors first; inherited destructors
>last.

This is not a firm rule, though if you wanted to argue that it's good
form I wouldn't complain.  One place I've found it useful to delay the
inherited constructor is in creating threads, where the constructor sets
up some data that will be used in the Execute method:

  constructor TSomeThread.Create(CreateSuspended: Boolean);
  begin
    FSomethingUsedByExecute := SomeValue;
    inherited Create(CreateSuspended);
  end;

If you called inherited Create first, you might find that Execute tried
to use the data before you initialized it.  If you insist on calling the
inherited constructor first, you should write:

  constructor TSomeThread.Create(CreateSuspended: Boolean);
  begin
    inherited Create(true);
    FSomethingUsedByExecute := SomeValue;
    if not CreateSuspended then
      Resume;
  end;

I used to write thread constructors that way, but got tired of it.

Quote
>(3) I recommend very strongly that you should set all pointers to NIL
>immediately after you free it.  And I don't give a <!> if Delphi
>suggests to you that you don't need it.  I once lost $10,000 in hard
>money to a double-free error caused by a garbage pointer in a
>destructor.
>(4) Test, with the de{*word*81}, to be certain that all of the constructor
>and destructor code actually is being called as you expect it will.

--
"The privileged being which we call human is distinguished from other
animals only by certain double-edged manifestations which in charity we
can only call 'inhuman.'" -- Epiktistes

Re:destructors


Quote
Sundial Services wrote:
> To elaborate:

> (1) You must override constructors and destructors.

    Yes and no. Yes: the reason I spoke up was because the
previous reply didn't say anything about overriding
Destroy - if you don't override Destroy then Free won't
work right.

    I think talking about "destructors" is misleading, actually:
If you're going to be using Free as usual it's _Destroy_ you
need to override, not some other destructor. (I don't think
there's ever a reason a class needs a destructor other than
Destroy - I've seen it stated that there's never any reason,
and I certainly can't think of any.)

    No: It's not even _possible_ to override a generic constructor.
If you're talking about virtual constructors (like components)
then of course yes. But if you try to override TList.Create
or TBitmap.Create you'll find it doesn't quite compile.

Quote
> (2) You must call inherited constructors first; inherited destructors
> last.
> (3) I recommend very strongly that you should set all pointers to NIL
> immediately after you free it.  And I don't give a <!> if Delphi
> suggests to you that you don't need it.  I once lost $10,000 in hard
> money to a double-free error caused by a garbage pointer in a
> destructor.

    If the way you're writing your programs is such that you need to
set pointers to nil then yes you do. It's possible to write Delphi
programs in a somewhat different style where setting the typical
pointer to nil would be totally irrelevant. Honest. That loss was
caused not just by the bad pointer, it was caused by the
combination of the bad pointer and the programming style
that required the nil. I write a lot of Delphi programs, I haven't
set a pointer to nil in a _long_ time, and there have been no
problems.
    In fact my programs are much more robust these days
than they were back when I used to set pointers to nil
because I hadn't yet figured out how to write in a style that
didn't require it.
Quote
> (4) Test, with the de{*word*81}, to be certain that all of the constructor
> and destructor code actually is being called as you expect it will.

> David C. Ullrich wrote:

> >     It's not just style - there's one right way to do this. You need to
> > override the Destroy method.

> >     That's _override_, not just "modify" or "change":

> > type
> >     TNewClass
> >         destructor Destroy; override;
> >     end;

> > If you leave out the "override" things won't work right.

> >     Then when you want to free one of your objects you
> > should call the Free method.

> > JJ wrote:

> > > I built a custom class with a memory built into it.

> > > to free the memory stream when I free the object, should I modify the Free
> > > or Destroy method of the parent class?

> > > I want to Free the inherited class with the free method, but I am interested
> > > in the conventionally accepted style.

> > > thanks,
> > > JJ

> --
> ------------------------------------------------------------------
> Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259
> mailto:i...@sundialservices.com  (PGP public key available.)
> > Fast(!), automatic table-repair with two clicks of the mouse!
> > ChimneySweep(R):  "Click click, it's fixed!" {tm}
> > http://www.sundialservices.com/products/chimneysweep

Re:destructors


Quote
Sundial Services wrote in message <38C1A6D2.2...@sundialservices.com>...
>To elaborate:

>(1) You must override constructors and destructors.
>(2) You must call inherited constructors first; inherited destructors
>last.
>(3) I recommend very strongly that you should set all pointers to NIL
>immediately after you free it.  And I don't give a <!> if Delphi
>suggests to you that you don't need it.  I once lost $10,000 in hard
>money to a double-free error caused by a garbage pointer in a
>destructor.

Delphi 5 now has a FreeAndNil procedure that frees an object
and sets the pointer to nil in one go, which can be useful.

Julian van Tubbergh.

Other Threads