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.
...
c:=c.tsomeclass.create;
c.freeandnil
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
freeandnil).
--- 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
doesn't?
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.
- ROW
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal