Recent

Author Topic: Class instantion syntax  (Read 4026 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12111
  • Debugger - SynEdit - and more
    • wiki
Re: Class instantion syntax
« Reply #15 on: September 01, 2018, 04:30:26 pm »
Well it is (as always) more complicated.

First of all, I have seen the "variable.create" error plenty of time. It is a very common mistake.
So it may well NOT be the best design.

My personal opinion....

If (hypothetically) we wanted to make changes, then limiting the behaviour to certain cases (drawing the line) would be a crude workaround at best.
On the one hand, yes, it would catch many/most erroneous uses.
On the other hand, it would add more rules. And those rules need to be learned by each programmer. That would actually make thinks more complicated (more rules > more complicated).

A constructor (for class based objects) does 2 things:
- allocating memory
- initializing the object

But when we call "inherited create" we do not need the allocation (in fact it must be skipped).
So the problem is, that we have 2 functionalities, but only one named method. That is obviously problematic.

Someone decided that the functionality should be chosen depending on the value/type of self.
- It may work well
- It is a simple rule (once you know it / it may be a painful learning experience to get to know it)
- It is not verbose at all.

So the hypothetical fix, would be to have a separate allocator, and initiator. Unfortunately this is incompatible. (And less convenient).

---------------------------
Btw:

variable.create should give you a warning about variable not being initialized.
If you compile with -Se, the the warning is treated as error, so you will not be able to compile this in most cases.

lucamar

  • Hero Member
  • *****
  • Posts: 4217
Re: Class instantion syntax
« Reply #16 on: September 01, 2018, 06:41:10 pm »
I have my own mental scheme (everyone has their own one) in which a very simple object have some kind of these steps

1.- Memory allocation -> constructor
2.- Variable initialization -> init
3.- Do things -> whatever else
4.- Free the object -> free (or freeandnil).

Computer language syntax is, after all, merely a learned convention. Once you get accustomed to doing things in a certain way, you don't really think much about it and so it feels completely natural to use

    Instance := TObject.Create;

But yeah, sometimes I find myself on a mental scheme similar to yours---usually while maintaining very old code bases---and it makes me think that the old Turbo-way of using
Code: Pascal  [Select][+][-]
  1. New(PObjact, Init(params)); {Your steps 1 & 2 combined}
  2. PObject^.DoThings;          { step 3 }
  3. Dispose(PObject, Done);     { and step 4 w/ explicit destructor call }
  4.  
was more logical (except for the pointer thing!).

Looking more closely, though, it just happens that it's all the same. As the old TP55 manual says:
Quote
When you use this extended syntax for New, the constructor actually performs the dynamic allocation, using special entry code generated as part of a constructor's compilation*. The instance name cannot precede Init, since at the time New is called, the instance being initialized with Init does not yet exist. The compiler identifies the correct Init method to call through the type of the pointer passed as the first parameter.

(* emphasis mine)

In the end, the question is clear: Are you calling the constructor as constructor or as method? If as constructor, then having to use AnObject := TSomeClass.Create; serves---even if just mentally---to emphasize the distinction. And remember that nothing prevents you from having an Initialize method which you can call from your constructor ... or from elsewhere.
« Last Edit: September 01, 2018, 07:03:27 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

 

TinyPortal © 2005-2018