Board index » delphi » Basic constructor question.

Basic constructor question.

Hi all.

Is a constructor method a function or a procedure?  Should it return a
result (function) to the calling program or not (procedure)?  Or can
you use it either way?

public
  constructor init;

or

public
  constructor init(a, b, c);

Also should I use the name create to keep to the standards?

Your answers on a postcard to.... :)

Thanks.

--
Mike Barnard, UK.
Using Delphi 5 trial version.
Teaching myself at home from books as best as I can.
NO real programming training.
Having fun! Wierd, ain't I. :)

 

Re:Basic constructor question.


"Mike Barnard" <m...@thunderin.co.uk> skrev i melding
news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...

Quote
> Hi all.

> Is a constructor method a function or a procedure?  Should it return a
> result (function) to the calling program or not (procedure)?  Or can
> you use it either way?

> public
>   constructor init;

> or

> public
>   constructor init(a, b, c);

> Also should I use the name create to keep to the standards?

> Your answers on a postcard to.... :)

A constructor is a special case - syntactically it's close to a function but
it's actually not. The reason: Allocation of the memory block representing
the 'object' is done by compiler magic *before* the constructor is called.
The constructor is a method of the recently created object that is called
just like any other method. The object is perfectly valid when you enter the
constructor, so it doesn't matter what order you do things:

type TMyObject = class
  FList: TList;
  FID: integer;
  constructor create(const AID: integer);
  destructor destroy;
end;

...a few valid constructors for this class:

constructor TMyObject.Create(const AID: integer);
begin
  inherited Create;
  FList:=TList.Create;
  FID:=AID;
end;

constructor TMyObject.Create(const AID: integer);
begin
  FID:=AID;
  FList:=TList.Create;
  inherited Create;
end;

constructor TMyObject.Create(const AID: integer);
begin
  FID:=AID;
  FList:=TList.Create;
// inherited create; doesn't do anything in this case,
// so you may as well leave it out...
end;

now, the object may be constructed in at least two ways:

var
  Obj: TMyObject;

  Obj:=TMyObject.Create(1);

  Obj:=TMyObject.Create; // creates the instance...
  Obj.Create(1); // Calls the Create as a regular method...

...btw, I believe you may find more about this under "Constructor" in Delphi
help file...
--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)

Re:Basic constructor question.


Quote
"Mike Barnard" <m...@thunderin.co.uk> wrote in message

news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...

Quote
> Hi all.

> Is a constructor method a function or a procedure?  Should it return a
> result (function) to the calling program or not (procedure)?  Or can
> you use it either way?

One shouldn't consider a constructor as anything but a constructor. Its
calling syntax closely resembles that of a class function. However so much
special code is added by the compiler when a constructor is called with a
class reference that one should never consider the call a function call.
Within a constructor one does not assign a return value, this is handled,
when needed, by the compiler. I'd suggest that you read the Object Pascal
Reference entry on Constructors. It will clarify things for you.

Re:Basic constructor question.


On Wed, 2 Jan 2002 23:22:26 -0500, "Bruce Roberts"

Quote
<b...@bounceitattcanada.xnet> wrote:

>"Mike Barnard" <m...@thunderin.co.uk> wrote in message
>news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...
>> Hi all.

>> Is a constructor method a function or a procedure?  Should it return a
>> result (function) to the calling program or not (procedure)?  Or can
>> you use it either way?

>One shouldn't consider a constructor as anything but a constructor. Its
>calling syntax closely resembles that of a class function. However so much
>special code is added by the compiler when a constructor is called with a
>class reference that one should never consider the call a function call.
>Within a constructor one does not assign a return value, this is handled,
>when needed, by the compiler. I'd suggest that you read the Object Pascal
>Reference entry on Constructors. It will clarify things for you.

Thanks, I will.  Lots to learn... lots and lots! :)

--
Mike Barnard, UK.
Using Delphi 5 trial version.
Teaching myself at home from books as best as I can.
NO real programming training.
Having fun! Wierd, ain't I. :)

Re:Basic constructor question.


Quote
Bruce Roberts wrote in message ...

>"Mike Barnard" <m...@thunderin.co.uk> wrote in message
>news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...
>> Hi all.

>> Is a constructor method a function or a procedure?  Should it return a
>> result (function) to the calling program or not (procedure)?  Or can
>> you use it either way?

>One shouldn't consider a constructor as anything but a constructor. Its
>calling syntax closely resembles that of a class function. However so much
>special code is added by the compiler when a constructor is called with a
>class reference that one should never consider the call a function call.
>Within a constructor one does not assign a return value, this is handled,
>when needed, by the compiler. I'd suggest that you read the Object Pascal
>Reference entry on Constructors. It will clarify things for you.

You have a point, and yet I disagree. A constructor _is_ a special
case, but it can be used as an ordinary method. In that case, it
should clean out and re-initialise the object on which it was called.
This is documented, and can be obtained in all cases through judicious
programming.

Its being a special case comes down to two things: memory allocation
(the easy part; simply happens exactly once before the constructor
proper is entered), and the fact that a constructor can be used both
as a class method and as an object method. Even the latter is quite
simple once you see it. Don't forget that "inherited Create" also
uses the constructor as an object method, the initialiser-only kind.

Groetjes,
Maarten Wiltink

Re:Basic constructor question.


"Bruce Roberts" <b...@bounceitattcanada.xnet> skrev i melding
news:s7RY7.8262$Q06.53166@tor-nn1.netcom.ca...

Quote

> "Mike Barnard" <m...@thunderin.co.uk> wrote in message
> news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...
> > Hi all.

> > Is a constructor method a function or a procedure?  Should it return a
> > result (function) to the calling program or not (procedure)?  Or can
> > you use it either way?

> One shouldn't consider a constructor as anything but a constructor. Its
> calling syntax closely resembles that of a class function. However so much
> special code is added by the compiler when a constructor is called with a
> class reference that one should never consider the call a function call.
> Within a constructor one does not assign a return value, this is handled,
> when needed, by the compiler.

Actually, the constructor does not return a value. The instance is the
'self'. It is the construct

  ObjectVar:=TObject.Create;

..that looks as if the method returns an object. I believe this pseudo code
is more or less describing what happens:

what you write:

  ObjectVar:=TObject.Create;

what you get:

  New(ObjectVar); <- Added by "Compiler Magic" (TM)
  ObjectVar.Create; <- A regular method call

The only thing that obscures this is, if the constructor crashes, the object
is freed...so this may be a more exact model:

try
  New(ObjectVar); <- Added by "Compiler Magic" (TM)
  ObjectVar.Create; <- A regular method call
except
  ObjectVar.Free;
end;

...I believe we had a rather lengthy, tough discussion on this topic a year
or two ago...;-)

--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)

Re:Basic constructor question.


"Maarten Wiltink" <maar...@kittensandcats.net> skrev i melding
news:a11aha$ac7$1@news1.xs4all.nl...

Quote
> Bruce Roberts wrote in message ...

> >"Mike Barnard" <m...@thunderin.co.uk> wrote in message
> >news:it263u016no5g6ducdcmesimb3of0nvnvk@4ax.com...
> >> Hi all.

> >> Is a constructor method a function or a procedure?  Should it return a
> >> result (function) to the calling program or not (procedure)?  Or can
> >> you use it either way?

> >One shouldn't consider a constructor as anything but a constructor. Its
> >calling syntax closely resembles that of a class function. However so much
> >special code is added by the compiler when a constructor is called with a
> >class reference that one should never consider the call a function call.
> >Within a constructor one does not assign a return value, this is handled,
> >when needed, by the compiler. I'd suggest that you read the Object Pascal
> >Reference entry on Constructors. It will clarify things for you.

> You have a point, and yet I disagree. A constructor _is_ a special
> case, but it can be used as an ordinary method. In that case, it
> should clean out and re-initialise the object on which it was called.
> This is documented, and can be obtained in all cases through judicious
> programming.

The constructor does not 'clean' the object. To use the constructor for
initializing an existing instance (that has allready run it) you need to
provide code for this, e.g. by clearing string fields, freeing subobjects,
etc.

Quote
> Its being a special case comes down to two things: memory allocation
> (the easy part; simply happens exactly once before the constructor
> proper is entered), and the fact that a constructor can be used both
> as a class method and as an object method. Even the latter is quite
> simple once you see it. Don't forget that "inherited Create" also
> uses the constructor as an object method, the initialiser-only kind.

When the constructor is called, it does *nothing* more than what the visible
code lines inside the constructor tells it to do. The compiler magic has
allready done its stuff. TObject.Create; is an empty method, and 'Inherited
Create' calls the object method the same way - as a regular object method...
--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)

Re:Basic constructor question.


Quote
Bj?rge S?ther wrote in message ...
>"Maarten Wiltink" <maar...@kittensandcats.net> skrev i melding
>news:a11aha$ac7$1@news1.xs4all.nl...
[...]
>> [A constructor] can be used as an ordinary method. In that case, it
>> should clean out and re-initialise the object on which it was called.
>> This is documented, and can be obtained in all cases through judicious
>> programming.

>The constructor does not 'clean' the object. To use the constructor for
>initializing an existing instance (that has allready run it) you need to
>provide code for this, e.g. by clearing string fields, freeing subobjects,
>etc.

And all constructors SHOULD implement this functionality. As I said,
this is documented, and can be obtained in all cases through judicious
programming. It does not clash with the use of a constructor for
generating a new object instance; in fact, it meshes quite well with
the statement (made here some time ago) that destructors should be
prepared to deal with partially-initialised objects. The same goes
for constructors. They should Wipe, Init and Setup the object under
scrutiny, whereas the destructor should only Wipe it, but in exactly
the same way as the constructor.

(Wipe, Init, and Setup are capitalised because they are private
procedures in all my object classes, called from both constructors
and destructors.)

Quote
>> Its being a special case comes down to two things: memory allocation
>> (the easy part; simply happens exactly once before the constructor
>> proper is entered), and the fact that a constructor can be used both
>> as a class method and as an object method. Even the latter is quite
>> simple once you see it. Don't forget that "inherited Create" also
>> uses the constructor as an object method, the initialiser-only kind.

>When the constructor is called, it does *nothing* more than what the
visible
>code lines inside the constructor tells it to do. The compiler magic has
>allready done its stuff. TObject.Create; is an empty method, and
'Inherited
>Create' calls the object method the same way - as a regular object

method...

You seem to be disagreeing with the preceding paragraph, yet I do not
see any contradictions between them. Are you?

Groetjes,
Maarten Wiltink

Re:Basic constructor question.


Quote
> Bj?rge S?ther wrote in message ...
> >"Maarten Wiltink" <maar...@kittensandcats.net> skrev i melding
> >news:a11aha$ac7$1@news1.xs4all.nl...
> [...]
> >> [A constructor] can be used as an ordinary method. In that case, it
> >> should clean out and re-initialise the object on which it was called.
> >> This is documented, and can be obtained in all cases through judicious
> >> programming.

> >The constructor does not 'clean' the object. To use the constructor for
> >initializing an existing instance (that has allready run it) you need to
> >provide code for this, e.g. by clearing string fields, freeing subobjects,
> >etc.

> And all constructors SHOULD implement this functionality. As I said,
> this is documented, and can be obtained in all cases through judicious
> programming. It does not clash with the use of a constructor for
> generating a new object instance; in fact, it meshes quite well with
> the statement (made here some time ago) that destructors should be
> prepared to deal with partially-initialised objects. The same goes
> for constructors. They should Wipe, Init and Setup the object under
> scrutiny, whereas the destructor should only Wipe it, but in exactly
> the same way as the constructor.

> (Wipe, Init, and Setup are capitalised because they are private
> procedures in all my object classes, called from both constructors
> and destructors.)

I believe I never Wipe an object, I recreate it instead . I find calling
'Wipe' in every constructor to be superflous as I don't ever do it. Well, I
don't say ever, but *rarely*, at least. I have never called Create on an
instantiated object either. I believe I call such a method Initialize;
instead.
One thing that makes it a bit difficult to use this "old-fashioned" (it was
done this way in old TurboPascal) scheme is the fact that destroy; is *not*
handled the same way. You can't (to my knowledge) call the destructor without
having the instance deallocated. One use for a Wipe procedure could be for
saving memory when objects are out of scope, much like
TWinControl.ReleaseHandle;.

--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)
"Maarten Wiltink" <maar...@kittensandcats.net> skrev i melding
news:a11n7k$gtn$1@news1.xs4all.nl...

Re:Basic constructor question.


On Wed, 02 Jan 2002 13:31:32 +0000, Mike Barnard

Quote
<m...@thunderin.co.uk> wrote:
>Hi all.

>Is a constructor method a function or a procedure?

Yes. (sorry...)

Quote
> Should it return a
>result (function) to the calling program or not (procedure)?

No.

Quote
> Or can
>you use it either way?

>public
>  constructor init;

>or

>public
>  constructor init(a, b, c);

??? These are not two different ways to use a constructor,
they're two different constructors.

Quote
>Also should I use the name create to keep to the standards?

There's never a reason for more than one destructor, and your
destructor needs to be named Destroy or things won't work
right (this is an error in the docs - in many places they
say "the destructor" where they should say "Destroy".)

But it can happen that you want more than one constructor,
and you can't give them the same name, so constructors
with funny names are allowed. Not that I see _why_ you're
not calling it Create...

Quote
>Your answers on a postcard to.... :)

>Thanks.

>--
>Mike Barnard, UK.
>Using Delphi 5 trial version.
>Teaching myself at home from books as best as I can.
>NO real programming training.
>Having fun! Wierd, ain't I. :)

David C. Ullrich

Re:Basic constructor question.


Quote
"Bj?rge S?ther" <REMOVE_bsaether@THIS_online.no> wrote in message

news:u9XY7.17300

Quote
> Actually, the constructor does not return a value. The instance is the
> 'self'. It is the construct

>   ObjectVar:=TObject.Create;

> ..that looks as if the method returns an object. I believe this pseudo
code
> is more or less describing what happens:

> what you write:

>   ObjectVar:=TObject.Create;

> what you get:

>   New(ObjectVar); <- Added by "Compiler Magic" (TM)
>   ObjectVar.Create; <- A regular method call

I don't entirely agree. Two reasons, were your psuedo code correct one
couldn't do
    with tObject.Create do
Second a quote from the OP Reference entry on constructors ". . .Finally,
the constructor returns a reference to the newly allocated and initialized
object. . . ."

I suspect that the more likely scenario for tSomeClass.Create is a call to
something like CreateANewInstance:

function CreateANewInstance (aClass : tClass) : tObject

begin
result := AllocMem (aClass.InstanceSize)
try
    result.Create
except
    result.Destroy
    raise
    end
end

Which allows for
    ObjectVar := tObject.Create;
and
    with tObject.Create do

Re:Basic constructor question.


Quote
"Maarten Wiltink" <maar...@kittensandcats.net> wrote in message

news:a11aha$ac7

Quote
> You have a point, and yet I disagree. A constructor _is_ a special
> case, but it can be used as an ordinary method. In that case, it
> should clean out and re-initialise the object on which it was called.
> This is documented, and can be obtained in all cases through judicious
> programming.

You are quite correct in the mechanics. What I have been wondering about is
the validity of the model. The OP reference seems quite clear that
constructors can be used to reinitialize instances. Yet I don't recall any
examples of this in the VCL. In fact ISTM that many VCL classes would fail
if an instance method call was made of Create. So now I wonder if the
language designers had one vision and the VCL implementers another or is the
dual nature of the constructor a by product of its implementation.

Personally I'm not entirely comfortable with a constructor being used for
both instance construction and re-initialization. I think I would have much
preferred a constructor that only constructed and an initializor that
(re-)initialized.

Re:Basic constructor question.


"Bruce Roberts" <b...@bounceitattcanada.xnet> skrev i melding
news:4N1Z7.8355$Q06.54287@tor-nn1.netcom.ca...

Quote

> "Bj?rge S?ther" <REMOVE_bsaether@THIS_online.no> wrote in message
> news:u9XY7.17300

> > Actually, the constructor does not return a value. The instance is the
> > 'self'. It is the construct

> >   ObjectVar:=TObject.Create;

> > ..that looks as if the method returns an object. I believe this pseudo
> code
> > is more or less describing what happens:

> > what you write:

> >   ObjectVar:=TObject.Create;

> > what you get:

> >   New(ObjectVar); <- Added by "Compiler Magic" (TM)
> >   ObjectVar.Create; <- A regular method call

> I don't entirely agree. Two reasons, were your psuedo code correct one
> couldn't do
>     with tObject.Create do
> Second a quote from the OP Reference entry on constructors ". . .Finally,
> the constructor returns a reference to the newly allocated and initialized
> object. . . ."

Yes, but as we have seen, this is an "oversimplification" - it isn't the
create method that returns the instance...but compiler magic does (implicit
calls inserted by the compiler)

- Show quoted text -

Quote
> I suspect that the more likely scenario for tSomeClass.Create is a call to
> something like CreateANewInstance:

> function CreateANewInstance (aClass : tClass) : tObject

> begin
> result := AllocMem (aClass.InstanceSize)
> try
>     result.Create
> except
>     result.Destroy
>     raise
>     end
> end

> Which allows for
>     ObjectVar := tObject.Create;
> and
>     with tObject.Create do

You're probably right. ;-)

--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)

Re:Basic constructor question.


"Bruce Roberts" <b...@bounceitattcanada.xnet> skrev i melding
news:cW1Z7.8358$Q06.54299@tor-nn1.netcom.ca...

Quote

> "Maarten Wiltink" <maar...@kittensandcats.net> wrote in message
> news:a11aha$ac7

> > You have a point, and yet I disagree. A constructor _is_ a special
> > case, but it can be used as an ordinary method. In that case, it
> > should clean out and re-initialise the object on which it was called.
> > This is documented, and can be obtained in all cases through judicious
> > programming.

> You are quite correct in the mechanics. What I have been wondering about is
> the validity of the model. The OP reference seems quite clear that
> constructors can be used to reinitialize instances. Yet I don't recall any
> examples of this in the VCL. In fact ISTM that many VCL classes would fail
> if an instance method call was made of Create. So now I wonder if the
> language designers had one vision and the VCL implementers another or is
the
> dual nature of the constructor a by product of its implementation.

Maybe it wasn't intentional in the first place ? Maybe they implemented the
constructor compiler magic stuff and then just let the constructor be called
as any method ?
Borland Developer #1: "But if we do it like this, then the constructor would
be just a normal method call when invoked on an object variable !"
Borland Developer #2: "Well, does it really matter ?"

Quote
> Personally I'm not entirely comfortable with a constructor being used for
> both instance construction and re-initialization. I think I would have much
> preferred a constructor that only constructed and an initializor that
> (re-)initialized.

--
Bjoerge Saether
Asker, Norway
bjorge@hahaha_itte.no (remve the obvious)

Re:Basic constructor question.


In article <vuXY7.17319$KQ3.259...@news1.oke.nextra.no>, "Bj?rge S?ther"

Quote
<REMOVE_bsaether@THIS_online.no> writes:
>When the constructor is called, it does *nothing* more than what the visible
>code lines inside the constructor tells it to do. The compiler magic has
>allready done its stuff. TObject.Create; is an empty method, and 'Inherited
>Create' calls the object method the same way - as a regular object method...

That seems to be so, but how does the "compiler magic" know how much memory to
allocate unless it refers to ancestor Create's "compiler magic", and to do that
it must do more that a simple method call. Or is that referenc, to ancestor
Create's for memory allocation, part of the "compiler" magic.

Alan Lloyd
alangll...@aol.com

Go to page: [1] [2]

Other Threads