[fpc-pascal] Re: Constructors & Destructors 101
roward at mac.com
Fri Apr 3 16:51:23 CEST 2009
>> Thanks Jonas and Leledumbo for your answers. Most of this makes
>> sense to me now. Some minor followup questions / comments (snipped)
>> C) Just out of curiosity, am wondering why FreeAndNil is global
>> procedure instead of a method/destructor of TObject.
> then freeandnil would get, as first (hidden) parameter, the self
> pointer. However, this self pointer is a value parameter. So it
> would only contain the value of "c", not its address. Hence, there
> is no way to set "c" to nil inside the freeandnil method (while
> setting the instance variable to nil is the entire reason for using
--- And one of the features of FreeAndNil is to zero the reference
BEFORE deallocating the memory which I assume would be problematic to
do "inside" the instance in question.
>> 5) Although I can't remember reading it anywhere, I've noticed from
>> my own demo programs that the addresses of objects are initially
>> set to nil.
> That is not correct. All global variables (classes/objects or not)
> are initialized to 0/nil, but local variables aren't (except in case
> of reference-counted types). Moreover, the contents of a class
> instance are also zeroed when creating it.
--- Yes, I was only testing with global object variables. I also
noticed that the contents were initially set to zero on creation but
the address itself was not set to zero when destroying the object.
That bewilderment was cleared up by reading the docs more closely and
the answers I got here.
>> A) ...
>> What is it meant by: "no need to call [create] directly?" How do
>> you invoke the constructor without calling it?
> I think what is meant, is that if you create a __direct subclass__
> of TObject, ...
-- Yes, that makes sense
> ..there is no need to call TObject's create constructor (e.g., via
> "inherited create;") from your own constructors. It doesn't hurt if
> you do it of course, and may be good practice to account for future
> situations where the parent class may change.
-- As my own debugging aid to check for memory leaks, I've added a
global object counter to my own create and destroy routines which
keeps track of the net number of instances created/destroyed.
Although you probably would not want it in final release code, that
might be a situation where TObject.Create might do something.
>> ... and ... Why is create not virtual and the destroy destructor is?
> Because when creating a class instance, you usually know the exact
> class type of that instance ...
> ...Conversely, many routines that free a class instance, have no
> idea about the exact type of that instance ...
-- This is clear to me now.
>> B) ...
>> What is it meant by: "No other destructor should be implemented?"
> It means that you should not add "destructor
> my_peculiarly_named_destructor; virtual;" to your own classes. The
> reason is that TObject's free method, which is used by pretty much
> all code out there, is hardcoded to call "destroy". So if your
> destructor is named differently, a lot of existing code will not
> properly destroy instances of your class type.
--- Maybe a compiler warning for this situation is warranted?
>> ...and... Does it do "something" while the Create constructor
> No, TObject's default destructor does not do anything either.
--- I understand the semantics now. Neither does anything specific
but they do "do something"; allocate and deallocate memory as an
effect of the root class implementation.
More information about the fpc-pascal