views:

318

answers:

3

Is there difference in behavior between a constructor call and a procedure call in Delphi records? I have a D2010 code sample I want to convert to D2009 (which I am using). The sample uses a parameterless constructor, which is not permitted in Delphi 2009. If I substitute a simple parameterless procedure call, is there any functional difference for records?

I.E.

  TVector = record
  private
    FImpl: IVector;
  public
    constructor  Create;    // not allowed in D2009
  end;

becomes

  TVector = record
  private
    FImpl: IVector;
  public
    procedure  Create;    // so change to procedure
  end;

As far as I can see this should work, but I may be missing something.

A: 

A constructor is used to construct the record. It is called when the record is first created.

A function can and must be called as needed.

You can create a "constructing" procedure but you have to call it yourself.

TVector = record
private
  FImpl: IVector;
public
  procedure Create;
end;



var
  vec : TVector;
begin
  vec.Create;

An alternative is to create a factory function that returns the initialized record.

function CreateVector(): TVector;
begin
  Result.Create;
end;
Gamecat
As far as I could tell when testing in D2009, the Create constructor still has to be specifically called, it is not called automatically. I had expected the constructor to be called when the record comes in to scope, but cannot get it to do so. Does this happen in D2010?
HMcG
No, record constructors are not called automatically. There may be different constructors for different purposes, so which one should called automatically? A valid call can look like: aVector := TVector.Create;
Uwe Raabe
So, given that you have to call the constructor specifically, and records do not support inheritance, and records are instantiated automatically and therefore don't need to have a constructor, if there any practical difference that you can think of between constructor Create; andprocedure Create; ?
HMcG
A: 

One point of minor interest is that a record constructor assumedly needs to be treated a little special internally versus a normal method since records by default have a default parameterless constructor which would have to be overridden with your custom version.

The other obvious difference between record constructors and record procedures is that your constructors must have at least one parameter defined. (Since records don't allow for inheritance and the default constructor has no parameters.)

Darian Miller
Why? A constructor could simply be setting up initial values either entirely on it's own or obtaining them from some global source. (Admittedly I haven't tried it yet. I've had no need of a record constructor.)
Loren Pechtel
There is no such a thing as default constructor (and also default destructor) in Delphi at all. You can declare as many of different constructors/desctructors as you like, with any names and parameters, and none of these would be called implicitely. As for record, the record constructor is just a method.
Serg
Serg - Please try to create a record constructor with no parameters and report back your results. You should get this error:http://docwiki.embarcadero.com/RADStudio/en/E2394_Parameterless_constructors_not_allowed_on_record_types_(Delphi)I never said that a defined record constructor would be called implicitly. I said that by default, records assumedly have a parameterless constructor internally (which is the likely reason for this error since records do not support inheritance so apparently there's an internal default constructor considered at least.)
Darian Miller
Loren - I gave my reason why I assumed a record doesn't allow for a parameterless constructor. Either in Win32 there's a default constructor internally, or they are preparing for future compatibility... I don't know. The question wasn't 'why' the question was 'what is the difference' The difference IS in fact, that you cannot have a parameterless constructor. My answer stands as the proper answer but I cannot attest to internal workings of 'why'. All I have is E2394 error will result if you try it with a constructor and no error on a method = a marked difference.
Darian Miller
A: 

The record constructors are absolutely unnessessary misleading syntax sugar in native Win32 code. The only difference between record constructor and procedure is syntax:

TVector = record
  constructor Create;
end;

var
  vec : TVector;

begin
  vec:= TVector.Create;

and

TVector = record
  procedure Create;
end;

var
  vec : TVector;

begin
  vec.Create;

AFAIK there is a difference in .NET code (I am not using .NET)

Serg
I'm definitely veering towards this opinion. Looks as if for all practical purposes the functionality is the same - for some reason I was assuming a parameter-less constructor Create; would be automatically called in record instantiation, but it is not.
HMcG
@HMcG: There are no default constructors (and destructors) in Delphi. Every time the object is instantiated the constructor is called explicitely in code (though the call itself may be hidden somethere in VCL). As for records, there are no record destructors at all while record constructor is nothing more than a record method.
Serg
Fairly true, but your example code will not compile. (So there IS a slight difference between record constructors and methods as pointed out in my answer.)Try your code and you will get: [DCC Error] E2394 Parameterless constructors not allowed on record types
Darian Miller